* remote.c (get_memory_packet_size, set_thread)
[deliverable/binutils-gdb.git] / gdb / windows-nat.c
CommitLineData
24e60978 1/* Target-vector operations for controlling win32 child processes, for GDB.
0a65a603 2
197e01b6 3 Copyright (C) 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.
e88c49c3 7
24e60978
SC
8 This file is part of GDB.
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without eve nthe implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
197e01b6
EZ
22 Foundation, Inc., 51 Franklin Street, Fifth Floor,
23 Boston, MA 02110-1301, USA. */
24e60978 24
dfe7f3ac 25/* Originally by Steve Chamberlain, sac@cygnus.com */
24e60978 26
3cee93ac 27/* We assume we're being built with and will be used for cygwin. */
e88c49c3 28
24e60978
SC
29#include "defs.h"
30#include "frame.h" /* required by inferior.h */
31#include "inferior.h"
32#include "target.h"
60250e8b 33#include "exceptions.h"
24e60978
SC
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>
cad9cd60 46
24e60978 47#include "buildsym.h"
1ef980b9
SC
48#include "symfile.h"
49#include "objfiles.h"
24e60978 50#include "gdb_string.h"
fdfa3315 51#include "gdbthread.h"
24e60978 52#include "gdbcmd.h"
1750a5ef 53#include <sys/param.h>
1e37c281 54#include <unistd.h>
4646aa9d 55#include "exec.h"
3ee6f623 56#include "solist.h"
3cb8e7f6 57#include "solib.h"
24e60978 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
0714f9bf
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 };
0714f9bf 74#endif
8e860359
CF
75#include <sys/procfs.h>
76#include <psapi.h>
0714f9bf 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
3cee93ac
CF
85/* The string sent by cygwin when it processes a signal.
86 FIXME: This should be in a cygwin include file. */
3929abe9
CF
87#ifndef _CYGWIN_SIGNAL_STRING
88#define _CYGWIN_SIGNAL_STRING "cYgSiGw00f"
89#endif
3cee93ac 90
29fe111d 91#define CHECK(x) check (x, __FILE__,__LINE__)
dfe7f3ac 92#define DEBUG_EXEC(x) if (debug_exec) printf_unfiltered x
4e52d31c
PM
93#define DEBUG_EVENTS(x) if (debug_events) printf_unfiltered x
94#define DEBUG_MEM(x) if (debug_memory) printf_unfiltered x
95#define DEBUG_EXCEPT(x) if (debug_exceptions) printf_unfiltered x
24e60978 96
3ee6f623
CF
97static void win32_stop (void);
98static int win32_win32_thread_alive (ptid_t);
99static void win32_kill_inferior (void);
3cee93ac 100
7393af7c
PM
101static enum target_signal last_sig = TARGET_SIGNAL_0;
102/* Set if a signal was received from the debugged process */
103
3cee93ac
CF
104/* Thread information structure used to track information that is
105 not available in gdb's thread structure. */
106typedef struct thread_info_struct
3a4b77d8
JM
107 {
108 struct thread_info_struct *next;
109 DWORD id;
110 HANDLE h;
111 char *name;
112 int suspend_count;
3ade5333 113 int reload_context;
3a4b77d8 114 CONTEXT context;
1e37c281 115 STACKFRAME sf;
8e860359
CF
116 }
117thread_info;
1e37c281 118
29fe111d 119static thread_info thread_head;
24e60978 120
24e60978
SC
121/* The process and thread handles for the above context. */
122
3cee93ac
CF
123static DEBUG_EVENT current_event; /* The current debug event from
124 WaitForDebugEvent */
125static HANDLE current_process_handle; /* Currently executing process */
126static thread_info *current_thread; /* Info on currently selected thread */
349b409f 127static DWORD main_thread_id; /* Thread ID of the main thread */
24e60978
SC
128
129/* Counts of things. */
130static int exception_count = 0;
131static int event_count = 0;
dfe7f3ac 132static int saw_create;
24e60978
SC
133
134/* User options. */
135static int new_console = 0;
1e37c281 136static int new_group = 1;
dfe7f3ac
CF
137static int debug_exec = 0; /* show execution */
138static int debug_events = 0; /* show events from kernel */
139static int debug_memory = 0; /* show target memory accesses */
1ef980b9 140static int debug_exceptions = 0; /* show target exceptions */
dfe7f3ac
CF
141static int useshell = 0; /* use shell for subprocesses */
142
24e60978 143/* This vector maps GDB's idea of a register's number into an address
3cee93ac 144 in the win32 exception context vector.
24e60978 145
3cee93ac 146 It also contains the bit mask needed to load the register in question.
24e60978
SC
147
148 One day we could read a reg, we could inspect the context we
149 already have loaded, if it doesn't have the bit set that we need,
150 we read that set of registers in using GetThreadContext. If the
151 context already contains what we need, we just unpack it. Then to
152 write a register, first we have to ensure that the context contains
153 the other regs of the group, and then we copy the info in and set
154 out bit. */
155
3cee93ac
CF
156#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
157static const int mappings[] =
24e60978 158{
3a4b77d8
JM
159 context_offset (Eax),
160 context_offset (Ecx),
161 context_offset (Edx),
162 context_offset (Ebx),
163 context_offset (Esp),
164 context_offset (Ebp),
165 context_offset (Esi),
166 context_offset (Edi),
167 context_offset (Eip),
168 context_offset (EFlags),
169 context_offset (SegCs),
170 context_offset (SegSs),
171 context_offset (SegDs),
172 context_offset (SegEs),
173 context_offset (SegFs),
174 context_offset (SegGs),
175 context_offset (FloatSave.RegisterArea[0 * 10]),
176 context_offset (FloatSave.RegisterArea[1 * 10]),
177 context_offset (FloatSave.RegisterArea[2 * 10]),
178 context_offset (FloatSave.RegisterArea[3 * 10]),
179 context_offset (FloatSave.RegisterArea[4 * 10]),
180 context_offset (FloatSave.RegisterArea[5 * 10]),
181 context_offset (FloatSave.RegisterArea[6 * 10]),
182 context_offset (FloatSave.RegisterArea[7 * 10]),
1e37c281
JM
183 context_offset (FloatSave.ControlWord),
184 context_offset (FloatSave.StatusWord),
185 context_offset (FloatSave.TagWord),
186 context_offset (FloatSave.ErrorSelector),
187 context_offset (FloatSave.ErrorOffset),
188 context_offset (FloatSave.DataSelector),
189 context_offset (FloatSave.DataOffset),
d3a09475 190 context_offset (FloatSave.ErrorSelector)
97da3b20 191 /* XMM0-7 */ ,
441532d7
PM
192 context_offset (ExtendedRegisters[10*16]),
193 context_offset (ExtendedRegisters[11*16]),
194 context_offset (ExtendedRegisters[12*16]),
195 context_offset (ExtendedRegisters[13*16]),
196 context_offset (ExtendedRegisters[14*16]),
197 context_offset (ExtendedRegisters[15*16]),
198 context_offset (ExtendedRegisters[16*16]),
199 context_offset (ExtendedRegisters[17*16]),
200 /* MXCSR */
201 context_offset (ExtendedRegisters[24])
24e60978
SC
202};
203
d3a09475
JM
204#undef context_offset
205
24e60978
SC
206/* This vector maps the target's idea of an exception (extracted
207 from the DEBUG_EVENT structure) to GDB's idea. */
208
209struct xlate_exception
210 {
211 int them;
212 enum target_signal us;
213 };
214
24e60978
SC
215static const struct xlate_exception
216 xlate[] =
217{
218 {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV},
9cbf6c0e 219 {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV},
24e60978
SC
220 {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP},
221 {DBG_CONTROL_C, TARGET_SIGNAL_INT},
222 {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP},
7393af7c 223 {STATUS_FLOAT_DIVIDE_BY_ZERO, TARGET_SIGNAL_FPE},
24e60978
SC
224 {-1, -1}};
225
fa4ba8da
PM
226static void
227check (BOOL ok, const char *file, int line)
228{
229 if (!ok)
dfe7f3ac 230 printf_filtered ("error return %s:%d was %lu\n", file, line,
fa4ba8da
PM
231 GetLastError ());
232}
233
3cee93ac
CF
234/* Find a thread record given a thread id.
235 If get_context then also retrieve the context for this
236 thread. */
237static thread_info *
238thread_rec (DWORD id, int get_context)
24e60978 239{
3cee93ac
CF
240 thread_info *th;
241
3a4b77d8 242 for (th = &thread_head; (th = th->next) != NULL;)
3cee93ac
CF
243 if (th->id == id)
244 {
245 if (!th->suspend_count && get_context)
246 {
8a892701 247 if (get_context > 0 && id != current_event.dwThreadId)
3cee93ac
CF
248 th->suspend_count = SuspendThread (th->h) + 1;
249 else if (get_context < 0)
250 th->suspend_count = -1;
3ade5333 251 th->reload_context = 1;
3cee93ac
CF
252 }
253 return th;
254 }
255
256 return NULL;
257}
258
259/* Add a thread to the thread list */
260static thread_info *
3ee6f623 261win32_add_thread (DWORD id, HANDLE h)
3cee93ac
CF
262{
263 thread_info *th;
264
265 if ((th = thread_rec (id, FALSE)))
266 return th;
267
3929abe9 268 th = XZALLOC (thread_info);
3cee93ac
CF
269 th->id = id;
270 th->h = h;
271 th->next = thread_head.next;
272 thread_head.next = th;
39f77062 273 add_thread (pid_to_ptid (id));
dfe7f3ac 274 /* Set the debug registers for the new thread in they are used. */
fa4ba8da
PM
275 if (debug_registers_used)
276 {
277 /* Only change the value of the debug registers. */
278 th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
279 CHECK (GetThreadContext (th->h, &th->context));
280 th->context.Dr0 = dr[0];
281 th->context.Dr1 = dr[1];
282 th->context.Dr2 = dr[2];
283 th->context.Dr3 = dr[3];
284 /* th->context.Dr6 = dr[6];
285 FIXME: should we set dr6 also ?? */
286 th->context.Dr7 = dr[7];
287 CHECK (SetThreadContext (th->h, &th->context));
288 th->context.ContextFlags = 0;
289 }
3cee93ac 290 return th;
24e60978
SC
291}
292
3cee93ac
CF
293/* Clear out any old thread list and reintialize it to a
294 pristine state. */
24e60978 295static void
3ee6f623 296win32_init_thread_list (void)
24e60978 297{
3cee93ac
CF
298 thread_info *th = &thread_head;
299
3ee6f623 300 DEBUG_EVENTS (("gdb: win32_init_thread_list\n"));
3cee93ac
CF
301 init_thread_list ();
302 while (th->next != NULL)
24e60978 303 {
3cee93ac
CF
304 thread_info *here = th->next;
305 th->next = here->next;
306 (void) CloseHandle (here->h);
b8c9b27d 307 xfree (here);
24e60978 308 }
059198c1 309 thread_head.next = NULL;
3cee93ac
CF
310}
311
312/* Delete a thread from the list of threads */
313static void
3ee6f623 314win32_delete_thread (DWORD id)
3cee93ac
CF
315{
316 thread_info *th;
317
318 if (info_verbose)
39f77062
KB
319 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (pid_to_ptid (id)));
320 delete_thread (pid_to_ptid (id));
3cee93ac
CF
321
322 for (th = &thread_head;
323 th->next != NULL && th->next->id != id;
324 th = th->next)
325 continue;
326
327 if (th->next != NULL)
24e60978 328 {
3cee93ac
CF
329 thread_info *here = th->next;
330 th->next = here->next;
331 CloseHandle (here->h);
b8c9b27d 332 xfree (here);
24e60978
SC
333 }
334}
335
3cee93ac 336static void
3ee6f623 337do_win32_fetch_inferior_registers (int r)
24e60978 338{
1e37c281
JM
339 char *context_offset = ((char *) &current_thread->context) + mappings[r];
340 long l;
6c7de422 341
3ade5333 342 if (!current_thread)
d6dc8049
CF
343 return; /* Windows sometimes uses a non-existent thread id in its
344 events */
3ade5333
CF
345
346 if (current_thread->reload_context)
347 {
348 thread_info *th = current_thread;
349 th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
350 GetThreadContext (th->h, &th->context);
351 /* Copy dr values from that thread. */
352 dr[0] = th->context.Dr0;
353 dr[1] = th->context.Dr1;
354 dr[2] = th->context.Dr2;
355 dr[3] = th->context.Dr3;
356 dr[6] = th->context.Dr6;
357 dr[7] = th->context.Dr7;
358 current_thread->reload_context = 0;
359 }
360
6c7de422
MK
361#define I387_ST0_REGNUM I386_ST0_REGNUM
362
363 if (r == I387_FISEG_REGNUM)
1e37c281 364 {
8e860359 365 l = *((long *) context_offset) & 0xffff;
23a6d369 366 regcache_raw_supply (current_regcache, r, (char *) &l);
1e37c281 367 }
6c7de422 368 else if (r == I387_FOP_REGNUM)
1e37c281 369 {
8e860359 370 l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
23a6d369 371 regcache_raw_supply (current_regcache, r, (char *) &l);
1e37c281
JM
372 }
373 else if (r >= 0)
23a6d369 374 regcache_raw_supply (current_regcache, r, context_offset);
3cee93ac 375 else
24e60978
SC
376 {
377 for (r = 0; r < NUM_REGS; r++)
3ee6f623 378 do_win32_fetch_inferior_registers (r);
24e60978 379 }
6c7de422
MK
380
381#undef I387_ST0_REGNUM
3cee93ac
CF
382}
383
384static void
3ee6f623 385win32_fetch_inferior_registers (int r)
3cee93ac 386{
39f77062 387 current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
d6dc8049
CF
388 /* Check if current_thread exists. Windows sometimes uses a non-existent
389 thread id in its events */
3ade5333 390 if (current_thread)
3ee6f623 391 do_win32_fetch_inferior_registers (r);
3cee93ac
CF
392}
393
394static void
3ee6f623 395do_win32_store_inferior_registers (int r)
3cee93ac 396{
3ade5333 397 if (!current_thread)
d6dc8049 398 /* Windows sometimes uses a non-existent thread id in its events */;
3ade5333 399 else if (r >= 0)
822c9732
AC
400 regcache_raw_collect (current_regcache, r,
401 ((char *) &current_thread->context) + mappings[r]);
24e60978
SC
402 else
403 {
3cee93ac 404 for (r = 0; r < NUM_REGS; r++)
3ee6f623 405 do_win32_store_inferior_registers (r);
24e60978
SC
406 }
407}
408
3cee93ac
CF
409/* Store a new register value into the current thread context */
410static void
3ee6f623 411win32_store_inferior_registers (int r)
3cee93ac 412{
39f77062 413 current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
d6dc8049
CF
414 /* Check if current_thread exists. Windows sometimes uses a non-existent
415 thread id in its events */
3ade5333 416 if (current_thread)
3ee6f623 417 do_win32_store_inferior_registers (r);
3cee93ac 418}
24e60978 419
1e37c281
JM
420static int psapi_loaded = 0;
421static HMODULE psapi_module_handle = NULL;
8e860359
CF
422static BOOL WINAPI (*psapi_EnumProcessModules) (HANDLE, HMODULE *, DWORD, LPDWORD) = NULL;
423static BOOL WINAPI (*psapi_GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO, DWORD) = NULL;
424static DWORD WINAPI (*psapi_GetModuleFileNameExA) (HANDLE, HMODULE, LPSTR, DWORD) = NULL;
1e37c281 425
3ee6f623 426static int
8e860359 427psapi_get_dll_name (DWORD BaseAddress, char *dll_name_ret)
1e37c281
JM
428{
429 DWORD len;
430 MODULEINFO mi;
431 int i;
8e860359
CF
432 HMODULE dh_buf[1];
433 HMODULE *DllHandle = dh_buf;
1e37c281
JM
434 DWORD cbNeeded;
435 BOOL ok;
436
437 if (!psapi_loaded ||
8e860359
CF
438 psapi_EnumProcessModules == NULL ||
439 psapi_GetModuleInformation == NULL ||
440 psapi_GetModuleFileNameExA == NULL)
1e37c281 441 {
8e860359
CF
442 if (psapi_loaded)
443 goto failed;
1e37c281
JM
444 psapi_loaded = 1;
445 psapi_module_handle = LoadLibrary ("psapi.dll");
446 if (!psapi_module_handle)
8e860359
CF
447 {
448 /* printf_unfiltered ("error loading psapi.dll: %u", GetLastError ()); */
449 goto failed;
450 }
451 psapi_EnumProcessModules = GetProcAddress (psapi_module_handle, "EnumProcessModules");
1e37c281
JM
452 psapi_GetModuleInformation = GetProcAddress (psapi_module_handle, "GetModuleInformation");
453 psapi_GetModuleFileNameExA = (void *) GetProcAddress (psapi_module_handle,
8e860359
CF
454 "GetModuleFileNameExA");
455 if (psapi_EnumProcessModules == NULL ||
456 psapi_GetModuleInformation == NULL ||
457 psapi_GetModuleFileNameExA == NULL)
1e37c281
JM
458 goto failed;
459 }
460
461 cbNeeded = 0;
462 ok = (*psapi_EnumProcessModules) (current_process_handle,
8e860359
CF
463 DllHandle,
464 sizeof (HMODULE),
465 &cbNeeded);
1e37c281
JM
466
467 if (!ok || !cbNeeded)
468 goto failed;
469
8e860359 470 DllHandle = (HMODULE *) alloca (cbNeeded);
1e37c281
JM
471 if (!DllHandle)
472 goto failed;
473
474 ok = (*psapi_EnumProcessModules) (current_process_handle,
8e860359
CF
475 DllHandle,
476 cbNeeded,
477 &cbNeeded);
1e37c281
JM
478 if (!ok)
479 goto failed;
480
29fe111d 481 for (i = 0; i < (int) (cbNeeded / sizeof (HMODULE)); i++)
1e37c281
JM
482 {
483 if (!(*psapi_GetModuleInformation) (current_process_handle,
8e860359
CF
484 DllHandle[i],
485 &mi,
486 sizeof (mi)))
8a3fe4f8 487 error (_("Can't get module info"));
1e37c281
JM
488
489 len = (*psapi_GetModuleFileNameExA) (current_process_handle,
8e860359
CF
490 DllHandle[i],
491 dll_name_ret,
492 MAX_PATH);
1e37c281 493 if (len == 0)
8a3fe4f8 494 error (_("Error getting dll name: %u."), (unsigned) GetLastError ());
1e37c281
JM
495
496 if ((DWORD) (mi.lpBaseOfDll) == BaseAddress)
497 return 1;
498 }
499
500failed:
501 dll_name_ret[0] = '\0';
502 return 0;
503}
504
450005e7
CF
505/* Encapsulate the information required in a call to
506 symbol_file_add_args */
8a892701
CF
507struct safe_symbol_file_add_args
508{
509 char *name;
510 int from_tty;
511 struct section_addr_info *addrs;
512 int mainline;
513 int flags;
7c5c87c0 514 struct ui_file *err, *out;
8a892701
CF
515 struct objfile *ret;
516};
517
02e423b9 518/* Maintain a linked list of "so" information. */
3ee6f623 519struct lm_info
02e423b9 520{
02e423b9 521 DWORD load_addr;
3ee6f623
CF
522};
523
524static struct so_list solib_start, *solib_end;
02e423b9 525
450005e7
CF
526/* Call symbol_file_add with stderr redirected. We don't care if there
527 are errors. */
8a892701
CF
528static int
529safe_symbol_file_add_stub (void *argv)
530{
3ee6f623
CF
531#define p ((struct safe_symbol_file_add_args *) argv)
532 struct so_list *so = &solib_start;
02e423b9 533
8a892701
CF
534 p->ret = symbol_file_add (p->name, p->from_tty, p->addrs, p->mainline, p->flags);
535 return !!p->ret;
536#undef p
537}
538
450005e7 539/* Restore gdb's stderr after calling symbol_file_add */
8a892701 540static void
7c5c87c0 541safe_symbol_file_add_cleanup (void *p)
8a892701 542{
8e860359 543#define sp ((struct safe_symbol_file_add_args *)p)
450005e7 544 gdb_flush (gdb_stderr);
7c5c87c0 545 gdb_flush (gdb_stdout);
d3ff4a77 546 ui_file_delete (gdb_stderr);
7c5c87c0 547 ui_file_delete (gdb_stdout);
d3ff4a77 548 gdb_stderr = sp->err;
9d3789f7 549 gdb_stdout = sp->out;
8e860359 550#undef sp
8a892701
CF
551}
552
450005e7 553/* symbol_file_add wrapper that prevents errors from being displayed. */
8a892701
CF
554static struct objfile *
555safe_symbol_file_add (char *name, int from_tty,
556 struct section_addr_info *addrs,
557 int mainline, int flags)
8a892701
CF
558{
559 struct safe_symbol_file_add_args p;
560 struct cleanup *cleanup;
561
7c5c87c0 562 cleanup = make_cleanup (safe_symbol_file_add_cleanup, &p);
8a892701 563
7c5c87c0
CF
564 p.err = gdb_stderr;
565 p.out = gdb_stdout;
450005e7 566 gdb_flush (gdb_stderr);
7c5c87c0 567 gdb_flush (gdb_stdout);
d3ff4a77 568 gdb_stderr = ui_file_new ();
7c5c87c0 569 gdb_stdout = ui_file_new ();
8a892701
CF
570 p.name = name;
571 p.from_tty = from_tty;
572 p.addrs = addrs;
573 p.mainline = mainline;
574 p.flags = flags;
575 catch_errors (safe_symbol_file_add_stub, &p, "", RETURN_MASK_ERROR);
576
577 do_cleanups (cleanup);
578 return p.ret;
579}
580
3cb8e7f6
CF
581/* Get the loaded address of all sections, given that .text was loaded
582 at text_load. Assumes that all sections are subject to the same
583 relocation offset. Returns NULL if problems occur or if the
584 sections were not relocated. */
585
586static struct section_addr_info *
587get_relocated_section_addrs (bfd *abfd, CORE_ADDR text_load)
588{
589 struct section_addr_info *result = NULL;
590 int section_count = bfd_count_sections (abfd);
591 asection *text_section = bfd_get_section_by_name (abfd, ".text");
592 CORE_ADDR text_vma;
593
594 if (!text_section)
595 {
596 /* Couldn't get the .text section. Weird. */
597 }
598
599 else if (text_load == (text_vma = bfd_get_section_vma (abfd, text_section)))
600 {
601 /* DLL wasn't relocated. */
602 }
603
604 else
605 {
606 /* Figure out all sections' loaded addresses. The offset here is
607 such that taking a bfd_get_section_vma() result and adding
608 offset will give the real load address of the section. */
609
610 CORE_ADDR offset = text_load - text_vma;
611
612 struct section_table *table_start = NULL;
613 struct section_table *table_end = NULL;
614 struct section_table *iter = NULL;
615
616 build_section_table (abfd, &table_start, &table_end);
617
618 for (iter = table_start; iter < table_end; ++iter)
619 {
620 /* Relocated addresses. */
621 iter->addr += offset;
622 iter->endaddr += offset;
623 }
624
625 result = build_section_addr_info_from_section_table (table_start,
626 table_end);
627
628 xfree (table_start);
629 }
630
631 return result;
632}
633
634/* Add DLL symbol information. */
635static void
636solib_symbols_add (struct so_list *so, CORE_ADDR load_addr)
637{
638 struct section_addr_info *addrs = NULL;
639 static struct objfile *result = NULL;
640 char *name = so->so_name;
641 bfd *abfd = NULL;
642
643 /* The symbols in a dll are offset by 0x1000, which is the
644 the offset from 0 of the first byte in an image - because
645 of the file header and the section alignment. */
646
647 if (!name || !name[0])
648 return;
649
650 abfd = bfd_openr (name, "pei-i386");
651
652 if (!abfd)
653 {
654 /* pei failed - try pe */
655 abfd = bfd_openr (name, "pe-i386");
656 }
657
658 if (abfd)
659 {
660 if (bfd_check_format (abfd, bfd_object))
661 addrs = get_relocated_section_addrs (abfd, load_addr);
662
663 bfd_close (abfd);
664 }
665
666 if (addrs)
667 {
668 result = safe_symbol_file_add (name, 0, addrs, 0, OBJF_SHARED);
669 free_section_addr_info (addrs);
670 }
671 else
672 {
673 /* Fallback on handling just the .text section. */
674 struct cleanup *my_cleanups;
675
676 addrs = alloc_section_addr_info (1);
677 my_cleanups = make_cleanup (xfree, addrs);
678 addrs->other[0].name = ".text";
679 addrs->other[0].addr = load_addr;
680
681 result = safe_symbol_file_add (name, 0, addrs, 0, OBJF_SHARED);
682 do_cleanups (my_cleanups);
683 }
684
685 so->symbols_loaded = !!result;
686 return;
687}
688
450005e7 689/* Remember the maximum DLL length for printing in info dll command. */
3ee6f623 690static int max_dll_name_len;
450005e7 691
3cb8e7f6
CF
692static char *
693register_loaded_dll (const char *name, DWORD load_addr, int readsyms)
8e860359 694{
3ee6f623 695 struct so_list *so;
3f8ad85b
CF
696 char buf[MAX_PATH + 1];
697 char cwd[MAX_PATH + 1];
698 char *p;
699 WIN32_FIND_DATA w32_fd;
700 HANDLE h = FindFirstFile(name, &w32_fd);
5633f842 701 MEMORY_BASIC_INFORMATION m;
3f8ad85b
CF
702 size_t len;
703
6badb179
CF
704 if (h == INVALID_HANDLE_VALUE)
705 strcpy (buf, name);
706 else
3f8ad85b 707 {
c914e0cc
CF
708 FindClose (h);
709 strcpy (buf, name);
710 if (GetCurrentDirectory (MAX_PATH + 1, cwd))
711 {
712 p = strrchr (buf, '\\');
713 if (p)
714 p[1] = '\0';
715 SetCurrentDirectory (buf);
716 GetFullPathName (w32_fd.cFileName, MAX_PATH, buf, &p);
717 SetCurrentDirectory (cwd);
718 }
3f8ad85b
CF
719 }
720
3ee6f623
CF
721 if (strcasecmp (buf, "ntdll.dll") == 0)
722 {
723 GetSystemDirectory (buf, sizeof (buf));
724 strcat (buf, "\\ntdll.dll");
725 }
3929abe9 726 so = XZALLOC (struct so_list);
3ee6f623
CF
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
24e60978
SC
783/* Wait for child to do something. Return pid of child, or -1 in case
784 of error; store status through argument pointer OURSTATUS. */
1750a5ef 785static int
0a65a603 786handle_load_dll (void *dummy)
24e60978 787{
3a4b77d8 788 LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
3cee93ac 789 char dll_buf[MAX_PATH + 1];
450005e7 790 char *dll_name = NULL;
450005e7 791 char *p;
3cee93ac 792
3a4b77d8 793 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
3cee93ac 794
1e37c281 795 if (!psapi_get_dll_name ((DWORD) (event->lpBaseOfDll), dll_buf))
8e860359 796 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
3cee93ac 797
1e37c281 798 dll_name = dll_buf;
24e60978 799
dfe7f3ac
CF
800 if (*dll_name == '\0')
801 dll_name = get_image_name (current_process_handle, event->lpImageName, event->fUnicode);
3cee93ac
CF
802 if (!dll_name)
803 return 1;
804
3cb8e7f6 805 register_loaded_dll (dll_name, (DWORD) event->lpBaseOfDll + 0x1000, auto_solib_add);
3929abe9 806 solib_add (NULL, 0, NULL, auto_solib_add);
450005e7
CF
807
808 return 1;
809}
810
3ee6f623
CF
811static void
812win32_free_so (struct so_list *so)
813{
3ee6f623
CF
814 if (so->lm_info)
815 xfree (so->lm_info);
816}
817
3ee6f623
CF
818static void
819win32_relocate_section_addresses (struct so_list *so,
820 struct section_table *sec)
821{
822 /* FIXME */
823 return;
824}
825
3cb8e7f6
CF
826static void
827win32_solib_create_inferior_hook (void)
828{
829 solib_add (NULL, 0, NULL, auto_solib_add);
830 return;
831}
832
d3ff4a77 833static int
0a65a603 834handle_unload_dll (void *dummy)
d3ff4a77
CF
835{
836 DWORD lpBaseOfDll = (DWORD) current_event.u.UnloadDll.lpBaseOfDll + 0x1000;
3ee6f623 837 struct so_list *so;
d3ff4a77
CF
838
839 for (so = &solib_start; so->next != NULL; so = so->next)
3ee6f623 840 if (so->next->lm_info->load_addr == lpBaseOfDll)
d3ff4a77 841 {
3ee6f623 842 struct so_list *sodel = so->next;
d3ff4a77
CF
843 so->next = sodel->next;
844 if (!so->next)
845 solib_end = so;
3ee6f623 846 free_so (sodel);
3929abe9 847 solib_add (NULL, 0, NULL, auto_solib_add);
d3ff4a77
CF
848 return 1;
849 }
3929abe9 850
8a3fe4f8 851 error (_("Error: dll starting at 0x%lx not found."), (DWORD) lpBaseOfDll);
d3ff4a77
CF
852
853 return 0;
854}
855
450005e7 856/* Clear list of loaded DLLs. */
3ee6f623
CF
857static void
858win32_clear_solib (void)
450005e7 859{
450005e7
CF
860 solib_start.next = NULL;
861 solib_end = &solib_start;
862 max_dll_name_len = sizeof ("DLL Name") - 1;
863}
295732ea 864
3cb8e7f6
CF
865static void
866win32_special_symbol_handling (void)
867{
868 return;
869}
870
450005e7
CF
871/* Load DLL symbol info. */
872void
7470a420 873dll_symbol_command (char *args, int from_tty)
450005e7 874{
8e860359 875 int n;
450005e7 876 dont_repeat ();
8e860359 877
450005e7 878 if (args == NULL)
8a3fe4f8 879 error (_("dll-symbols requires a file name"));
450005e7 880
8e860359
CF
881 n = strlen (args);
882 if (n > 4 && strcasecmp (args + n - 4, ".dll") != 0)
883 {
884 char *newargs = (char *) alloca (n + 4 + 1);
885 strcpy (newargs, args);
886 strcat (newargs, ".dll");
887 args = newargs;
888 }
889
7470a420 890 safe_symbol_file_add (args, from_tty, NULL, 0, OBJF_SHARED | OBJF_USERLOADED);
8e860359 891}
450005e7 892
3cee93ac
CF
893/* Handle DEBUG_STRING output from child process.
894 Cygwin prepends its messages with a "cygwin:". Interpret this as
895 a Cygwin signal. Otherwise just print the string as a warning. */
896static int
897handle_output_debug_string (struct target_waitstatus *ourstatus)
898{
899 char *s;
900 int gotasig = FALSE;
901
902 if (!target_read_string
3a4b77d8 903 ((CORE_ADDR) current_event.u.DebugString.lpDebugStringData, &s, 1024, 0)
3cee93ac
CF
904 || !s || !*s)
905 return gotasig;
906
3929abe9 907 if (strncmp (s, _CYGWIN_SIGNAL_STRING, sizeof (_CYGWIN_SIGNAL_STRING) - 1) != 0)
3cee93ac 908 {
d3a09475 909 if (strncmp (s, "cYg", 3) != 0)
8a3fe4f8 910 warning (("%s"), s);
3cee93ac 911 }
d3a09475 912 else
3cee93ac
CF
913 {
914 char *p;
3929abe9 915 int sig = strtol (s + sizeof (_CYGWIN_SIGNAL_STRING) - 1, &p, 0);
1e37c281 916 gotasig = target_signal_from_host (sig);
0714f9bf
SS
917 ourstatus->value.sig = gotasig;
918 if (gotasig)
3cee93ac
CF
919 ourstatus->kind = TARGET_WAITKIND_STOPPED;
920 }
921
b8c9b27d 922 xfree (s);
3cee93ac
CF
923 return gotasig;
924}
24e60978 925
c1748f97
PM
926static int
927display_selector (HANDLE thread, DWORD sel)
928{
929 LDT_ENTRY info;
930 if (GetThreadSelectorEntry (thread, sel, &info))
931 {
932 int base, limit;
933 printf_filtered ("0x%03lx: ", sel);
934 if (!info.HighWord.Bits.Pres)
baa93fa6
CF
935 {
936 puts_filtered ("Segment not present\n");
937 return 0;
938 }
c1748f97
PM
939 base = (info.HighWord.Bits.BaseHi << 24) +
940 (info.HighWord.Bits.BaseMid << 16)
941 + info.BaseLow;
942 limit = (info.HighWord.Bits.LimitHi << 16) + info.LimitLow;
943 if (info.HighWord.Bits.Granularity)
caad7706 944 limit = (limit << 12) | 0xfff;
c1748f97
PM
945 printf_filtered ("base=0x%08x limit=0x%08x", base, limit);
946 if (info.HighWord.Bits.Default_Big)
baa93fa6 947 puts_filtered(" 32-bit ");
c1748f97 948 else
baa93fa6 949 puts_filtered(" 16-bit ");
c1748f97
PM
950 switch ((info.HighWord.Bits.Type & 0xf) >> 1)
951 {
952 case 0:
baa93fa6
CF
953 puts_filtered ("Data (Read-Only, Exp-up");
954 break;
c1748f97 955 case 1:
baa93fa6
CF
956 puts_filtered ("Data (Read/Write, Exp-up");
957 break;
c1748f97 958 case 2:
baa93fa6
CF
959 puts_filtered ("Unused segment (");
960 break;
c1748f97 961 case 3:
baa93fa6
CF
962 puts_filtered ("Data (Read/Write, Exp-down");
963 break;
c1748f97 964 case 4:
baa93fa6
CF
965 puts_filtered ("Code (Exec-Only, N.Conf");
966 break;
c1748f97 967 case 5:
baa93fa6 968 puts_filtered ("Code (Exec/Read, N.Conf");
c1748f97
PM
969 break;
970 case 6:
baa93fa6 971 puts_filtered ("Code (Exec-Only, Conf");
c1748f97
PM
972 break;
973 case 7:
baa93fa6 974 puts_filtered ("Code (Exec/Read, Conf");
c1748f97
PM
975 break;
976 default:
977 printf_filtered ("Unknown type 0x%x",info.HighWord.Bits.Type);
978 }
979 if ((info.HighWord.Bits.Type & 0x1) == 0)
baa93fa6 980 puts_filtered(", N.Acc");
c1748f97
PM
981 puts_filtered (")\n");
982 if ((info.HighWord.Bits.Type & 0x10) == 0)
983 puts_filtered("System selector ");
984 printf_filtered ("Priviledge level = %d. ", info.HighWord.Bits.Dpl);
985 if (info.HighWord.Bits.Granularity)
baa93fa6 986 puts_filtered ("Page granular.\n");
c1748f97
PM
987 else
988 puts_filtered ("Byte granular.\n");
989 return 1;
990 }
991 else
992 {
993 printf_filtered ("Invalid selector 0x%lx.\n",sel);
994 return 0;
995 }
996}
997
998static void
999display_selectors (char * args, int from_tty)
1000{
1001 if (!current_thread)
1002 {
1003 puts_filtered ("Impossible to display selectors now.\n");
1004 return;
1005 }
1006 if (!args)
1007 {
1008
1009 puts_filtered ("Selector $cs\n");
1010 display_selector (current_thread->h,
baa93fa6 1011 current_thread->context.SegCs);
c1748f97
PM
1012 puts_filtered ("Selector $ds\n");
1013 display_selector (current_thread->h,
baa93fa6 1014 current_thread->context.SegDs);
c1748f97
PM
1015 puts_filtered ("Selector $es\n");
1016 display_selector (current_thread->h,
baa93fa6 1017 current_thread->context.SegEs);
c1748f97
PM
1018 puts_filtered ("Selector $ss\n");
1019 display_selector (current_thread->h,
baa93fa6 1020 current_thread->context.SegSs);
c1748f97
PM
1021 puts_filtered ("Selector $fs\n");
1022 display_selector (current_thread->h,
1023 current_thread->context.SegFs);
1024 puts_filtered ("Selector $gs\n");
1025 display_selector (current_thread->h,
baa93fa6 1026 current_thread->context.SegGs);
c1748f97
PM
1027 }
1028 else
1029 {
1030 int sel;
1031 sel = parse_and_eval_long (args);
1032 printf_filtered ("Selector \"%s\"\n",args);
1033 display_selector (current_thread->h, sel);
1034 }
1035}
1036
1037static struct cmd_list_element *info_w32_cmdlist = NULL;
1038
1039static void
1040info_w32_command (char *args, int from_tty)
1041{
1042 help_list (info_w32_cmdlist, "info w32 ", class_info, gdb_stdout);
1043}
1044
1045
7393af7c 1046#define DEBUG_EXCEPTION_SIMPLE(x) if (debug_exceptions) \
4e52d31c 1047 printf_unfiltered ("gdb: Target exception %s at 0x%08lx\n", x, \
7393af7c
PM
1048 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress)
1049
36339ecd 1050static int
450005e7 1051handle_exception (struct target_waitstatus *ourstatus)
24e60978 1052{
3cee93ac 1053 thread_info *th;
29fe111d 1054 DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
3cee93ac 1055
29fe111d 1056 ourstatus->kind = TARGET_WAITKIND_STOPPED;
8a892701 1057
3cee93ac
CF
1058 /* Record the context of the current thread */
1059 th = thread_rec (current_event.dwThreadId, -1);
24e60978 1060
29fe111d 1061 switch (code)
24e60978 1062 {
1ef980b9 1063 case EXCEPTION_ACCESS_VIOLATION:
7393af7c
PM
1064 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ACCESS_VIOLATION");
1065 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
8da8e0b3
CF
1066 {
1067 char *fn;
1068 if (find_pc_partial_function ((CORE_ADDR) current_event.u.Exception
1069 .ExceptionRecord.ExceptionAddress,
1070 &fn, NULL, NULL)
1071 && strncmp (fn, "KERNEL32!IsBad", strlen ("KERNEL32!IsBad")) == 0)
1072 return 0;
1073 }
7393af7c
PM
1074 break;
1075 case STATUS_STACK_OVERFLOW:
1076 DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
1ef980b9 1077 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
7393af7c
PM
1078 break;
1079 case STATUS_FLOAT_DENORMAL_OPERAND:
1080 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
1081 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1082 break;
1083 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
1084 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
1085 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1086 break;
1087 case STATUS_FLOAT_INEXACT_RESULT:
1088 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
1089 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1090 break;
1091 case STATUS_FLOAT_INVALID_OPERATION:
1092 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
1093 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1094 break;
1095 case STATUS_FLOAT_OVERFLOW:
1096 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
1097 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1098 break;
1099 case STATUS_FLOAT_STACK_CHECK:
1100 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
1101 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1ef980b9 1102 break;
3b7c8b74 1103 case STATUS_FLOAT_UNDERFLOW:
7393af7c
PM
1104 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
1105 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1106 break;
3b7c8b74 1107 case STATUS_FLOAT_DIVIDE_BY_ZERO:
7393af7c
PM
1108 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
1109 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1110 break;
3b7c8b74 1111 case STATUS_INTEGER_DIVIDE_BY_ZERO:
7393af7c 1112 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
3b7c8b74 1113 ourstatus->value.sig = TARGET_SIGNAL_FPE;
3b7c8b74 1114 break;
7393af7c
PM
1115 case STATUS_INTEGER_OVERFLOW:
1116 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
1117 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1ef980b9
SC
1118 break;
1119 case EXCEPTION_BREAKPOINT:
7393af7c 1120 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
1ef980b9
SC
1121 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1122 break;
1123 case DBG_CONTROL_C:
7393af7c 1124 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
1ef980b9 1125 ourstatus->value.sig = TARGET_SIGNAL_INT;
5b421780
PM
1126 break;
1127 case DBG_CONTROL_BREAK:
7393af7c 1128 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
5b421780 1129 ourstatus->value.sig = TARGET_SIGNAL_INT;
1ef980b9
SC
1130 break;
1131 case EXCEPTION_SINGLE_STEP:
7393af7c 1132 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
1ef980b9
SC
1133 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1134 break;
8227c82d 1135 case EXCEPTION_ILLEGAL_INSTRUCTION:
7393af7c
PM
1136 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
1137 ourstatus->value.sig = TARGET_SIGNAL_ILL;
1138 break;
1139 case EXCEPTION_PRIV_INSTRUCTION:
1140 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
1141 ourstatus->value.sig = TARGET_SIGNAL_ILL;
1142 break;
1143 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
1144 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
8227c82d
CF
1145 ourstatus->value.sig = TARGET_SIGNAL_ILL;
1146 break;
1ef980b9 1147 default:
02e423b9
CF
1148 if (current_event.u.Exception.dwFirstChance)
1149 return 0;
29fe111d 1150 printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n",
3a4b77d8 1151 current_event.u.Exception.ExceptionRecord.ExceptionCode,
8e860359 1152 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress);
24e60978 1153 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
1ef980b9 1154 break;
24e60978 1155 }
24e60978 1156 exception_count++;
7393af7c 1157 last_sig = ourstatus->value.sig;
36339ecd 1158 return 1;
24e60978
SC
1159}
1160
3cee93ac
CF
1161/* Resume all artificially suspended threads if we are continuing
1162 execution */
1163static BOOL
3ee6f623 1164win32_continue (DWORD continue_status, int id)
3cee93ac
CF
1165{
1166 int i;
1167 thread_info *th;
1168 BOOL res;
1169
7393af7c
PM
1170 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, %s);\n",
1171 current_event.dwProcessId, current_event.dwThreadId,
dfe7f3ac 1172 continue_status == DBG_CONTINUE ?
7393af7c 1173 "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED"));
0714f9bf
SS
1174 res = ContinueDebugEvent (current_event.dwProcessId,
1175 current_event.dwThreadId,
1176 continue_status);
1e37c281 1177 continue_status = 0;
0714f9bf 1178 if (res)
3a4b77d8 1179 for (th = &thread_head; (th = th->next) != NULL;)
29fe111d 1180 if (((id == -1) || (id == (int) th->id)) && th->suspend_count)
3cee93ac 1181 {
fa4ba8da 1182
3cee93ac
CF
1183 for (i = 0; i < th->suspend_count; i++)
1184 (void) ResumeThread (th->h);
1185 th->suspend_count = 0;
fa4ba8da
PM
1186 if (debug_registers_changed)
1187 {
3ade5333 1188 /* Only change the value of the debug registers */
fa4ba8da
PM
1189 th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
1190 th->context.Dr0 = dr[0];
1191 th->context.Dr1 = dr[1];
1192 th->context.Dr2 = dr[2];
1193 th->context.Dr3 = dr[3];
1194 /* th->context.Dr6 = dr[6];
dfe7f3ac 1195 FIXME: should we set dr6 also ?? */
fa4ba8da
PM
1196 th->context.Dr7 = dr[7];
1197 CHECK (SetThreadContext (th->h, &th->context));
1198 th->context.ContextFlags = 0;
1199 }
3cee93ac
CF
1200 }
1201
fa4ba8da 1202 debug_registers_changed = 0;
3cee93ac
CF
1203 return res;
1204}
1205
d6dc8049
CF
1206/* Called in pathological case where Windows fails to send a
1207 CREATE_PROCESS_DEBUG_EVENT after an attach. */
3ee6f623 1208static DWORD
5439edaa 1209fake_create_process (void)
3ade5333
CF
1210{
1211 current_process_handle = OpenProcess (PROCESS_ALL_ACCESS, FALSE,
1212 current_event.dwProcessId);
1213 main_thread_id = current_event.dwThreadId;
3ee6f623 1214 current_thread = win32_add_thread (main_thread_id,
3ade5333
CF
1215 current_event.u.CreateThread.hThread);
1216 return main_thread_id;
1217}
1218
8a892701
CF
1219/* Get the next event from the child. Return 1 if the event requires
1220 handling by WFI (or whatever).
1221 */
1e37c281 1222static int
3ee6f623 1223get_win32_debug_event (int pid, struct target_waitstatus *ourstatus)
1e37c281
JM
1224{
1225 BOOL debug_event;
8a892701 1226 DWORD continue_status, event_code;
87a45c96 1227 thread_info *th;
8a892701 1228 static thread_info dummy_thread_info;
450005e7 1229 int retval = 0;
1e37c281 1230
7393af7c 1231 last_sig = TARGET_SIGNAL_0;
9d3789f7 1232
8a892701 1233 if (!(debug_event = WaitForDebugEvent (&current_event, 1000)))
29fe111d 1234 goto out;
1e37c281
JM
1235
1236 event_count++;
1237 continue_status = DBG_CONTINUE;
1e37c281 1238
8a892701 1239 event_code = current_event.dwDebugEventCode;
450005e7 1240 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
87a45c96 1241 th = NULL;
8a892701
CF
1242
1243 switch (event_code)
1e37c281
JM
1244 {
1245 case CREATE_THREAD_DEBUG_EVENT:
1246 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
8a892701
CF
1247 (unsigned) current_event.dwProcessId,
1248 (unsigned) current_event.dwThreadId,
1249 "CREATE_THREAD_DEBUG_EVENT"));
dfe7f3ac 1250 if (saw_create != 1)
3ade5333
CF
1251 {
1252 if (!saw_create && attach_flag)
1253 {
d6dc8049
CF
1254 /* Kludge around a Windows bug where first event is a create
1255 thread event. Caused when attached process does not have
1256 a main thread. */
3ade5333
CF
1257 retval = ourstatus->value.related_pid = fake_create_process ();
1258 saw_create++;
1259 }
1260 break;
1261 }
1e37c281 1262 /* Record the existence of this thread */
3ee6f623 1263 th = win32_add_thread (current_event.dwThreadId,
8a892701 1264 current_event.u.CreateThread.hThread);
1e37c281
JM
1265 if (info_verbose)
1266 printf_unfiltered ("[New %s]\n",
39f77062
KB
1267 target_pid_to_str (
1268 pid_to_ptid (current_event.dwThreadId)));
450005e7 1269 retval = current_event.dwThreadId;
1e37c281
JM
1270 break;
1271
1272 case EXIT_THREAD_DEBUG_EVENT:
1273 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1274 (unsigned) current_event.dwProcessId,
1275 (unsigned) current_event.dwThreadId,
1276 "EXIT_THREAD_DEBUG_EVENT"));
87a45c96
CF
1277 if (current_event.dwThreadId != main_thread_id)
1278 {
3ee6f623 1279 win32_delete_thread (current_event.dwThreadId);
87a45c96
CF
1280 th = &dummy_thread_info;
1281 }
1e37c281
JM
1282 break;
1283
1284 case CREATE_PROCESS_DEBUG_EVENT:
1285 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1286 (unsigned) current_event.dwProcessId,
1287 (unsigned) current_event.dwThreadId,
1288 "CREATE_PROCESS_DEBUG_EVENT"));
700b351b 1289 CloseHandle (current_event.u.CreateProcessInfo.hFile);
dfe7f3ac
CF
1290 if (++saw_create != 1)
1291 {
1292 CloseHandle (current_event.u.CreateProcessInfo.hProcess);
1293 break;
1294 }
1e37c281 1295
dfe7f3ac 1296 current_process_handle = current_event.u.CreateProcessInfo.hProcess;
87a45c96 1297 if (main_thread_id)
3ee6f623 1298 win32_delete_thread (main_thread_id);
9d3789f7 1299 main_thread_id = current_event.dwThreadId;
1e37c281 1300 /* Add the main thread */
3ee6f623 1301 th = win32_add_thread (main_thread_id,
8a892701 1302 current_event.u.CreateProcessInfo.hThread);
9d3789f7 1303 retval = ourstatus->value.related_pid = current_event.dwThreadId;
1e37c281
JM
1304 break;
1305
1306 case EXIT_PROCESS_DEBUG_EVENT:
1307 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1308 (unsigned) current_event.dwProcessId,
1309 (unsigned) current_event.dwThreadId,
1310 "EXIT_PROCESS_DEBUG_EVENT"));
dfe7f3ac
CF
1311 if (saw_create != 1)
1312 break;
1e37c281
JM
1313 ourstatus->kind = TARGET_WAITKIND_EXITED;
1314 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
1315 CloseHandle (current_process_handle);
9d3789f7 1316 retval = main_thread_id;
8a892701 1317 break;
1e37c281
JM
1318
1319 case LOAD_DLL_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 "LOAD_DLL_DEBUG_EVENT"));
700b351b 1324 CloseHandle (current_event.u.LoadDll.hFile);
dfe7f3ac
CF
1325 if (saw_create != 1)
1326 break;
8a892701 1327 catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
1e37c281 1328 registers_changed (); /* mark all regs invalid */
450005e7
CF
1329 ourstatus->kind = TARGET_WAITKIND_LOADED;
1330 ourstatus->value.integer = 0;
9d3789f7 1331 retval = main_thread_id;
5633f842 1332 re_enable_breakpoints_in_shlibs ();
1e37c281
JM
1333 break;
1334
1335 case UNLOAD_DLL_DEBUG_EVENT:
1336 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1337 (unsigned) current_event.dwProcessId,
1338 (unsigned) current_event.dwThreadId,
1339 "UNLOAD_DLL_DEBUG_EVENT"));
dfe7f3ac
CF
1340 if (saw_create != 1)
1341 break;
d3ff4a77
CF
1342 catch_errors (handle_unload_dll, NULL, (char *) "", RETURN_MASK_ALL);
1343 registers_changed (); /* mark all regs invalid */
1344 /* ourstatus->kind = TARGET_WAITKIND_UNLOADED;
3bccec63 1345 does not exist yet. */
d3ff4a77 1346 break;
1e37c281
JM
1347
1348 case EXCEPTION_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 "EXCEPTION_DEBUG_EVENT"));
dfe7f3ac
CF
1353 if (saw_create != 1)
1354 break;
02e423b9
CF
1355 if (handle_exception (ourstatus))
1356 retval = current_event.dwThreadId;
8da8e0b3
CF
1357 else
1358 continue_status = DBG_EXCEPTION_NOT_HANDLED;
1e37c281
JM
1359 break;
1360
8a892701 1361 case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */
1e37c281 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 "OUTPUT_DEBUG_STRING_EVENT"));
dfe7f3ac
CF
1366 if (saw_create != 1)
1367 break;
8e860359 1368 if (handle_output_debug_string (ourstatus))
9d3789f7 1369 retval = main_thread_id;
1e37c281 1370 break;
9d3789f7 1371
1e37c281 1372 default:
dfe7f3ac
CF
1373 if (saw_create != 1)
1374 break;
29fe111d
CF
1375 printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
1376 (DWORD) current_event.dwProcessId,
1377 (DWORD) current_event.dwThreadId);
1378 printf_unfiltered (" unknown event code %ld\n",
1e37c281
JM
1379 current_event.dwDebugEventCode);
1380 break;
1381 }
1382
dfe7f3ac 1383 if (!retval || saw_create != 1)
3ee6f623 1384 CHECK (win32_continue (continue_status, -1));
450005e7 1385 else
9d3789f7 1386 {
39f77062 1387 inferior_ptid = pid_to_ptid (retval);
3ade5333 1388 current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE);
9d3789f7 1389 }
1e37c281
JM
1390
1391out:
450005e7 1392 return retval;
1e37c281
JM
1393}
1394
1e37c281 1395/* Wait for interesting events to occur in the target process. */
39f77062 1396static ptid_t
3ee6f623 1397win32_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
24e60978 1398{
39f77062
KB
1399 int pid = PIDGET (ptid);
1400
24e60978
SC
1401 /* We loop when we get a non-standard exception rather than return
1402 with a SPURIOUS because resume can try and step or modify things,
3cee93ac 1403 which needs a current_thread->h. But some of these exceptions mark
24e60978
SC
1404 the birth or death of threads, which mean that the current thread
1405 isn't necessarily what you think it is. */
1406
1407 while (1)
450005e7 1408 {
3ee6f623 1409 int retval = get_win32_debug_event (pid, ourstatus);
450005e7 1410 if (retval)
39f77062 1411 return pid_to_ptid (retval);
450005e7
CF
1412 else
1413 {
1414 int detach = 0;
3cee93ac 1415
98bbd631
AC
1416 if (deprecated_ui_loop_hook != NULL)
1417 detach = deprecated_ui_loop_hook (0);
0714f9bf 1418
450005e7 1419 if (detach)
3ee6f623 1420 win32_kill_inferior ();
450005e7
CF
1421 }
1422 }
24e60978
SC
1423}
1424
9d3789f7 1425static void
3ee6f623 1426do_initial_win32_stuff (DWORD pid)
9d3789f7
CF
1427{
1428 extern int stop_after_trap;
fa4ba8da 1429 int i;
9d3789f7 1430
7393af7c 1431 last_sig = TARGET_SIGNAL_0;
9d3789f7
CF
1432 event_count = 0;
1433 exception_count = 0;
fa4ba8da 1434 debug_registers_changed = 0;
dfe7f3ac 1435 debug_registers_used = 0;
fa4ba8da
PM
1436 for (i = 0; i < sizeof (dr) / sizeof (dr[0]); i++)
1437 dr[i] = 0;
9d3789f7
CF
1438 current_event.dwProcessId = pid;
1439 memset (&current_event, 0, sizeof (current_event));
3ee6f623 1440 push_target (&win32_ops);
5633f842 1441 disable_breakpoints_in_shlibs (1);
3ee6f623 1442 win32_clear_solib ();
9d3789f7
CF
1443 clear_proceed_status ();
1444 init_wait_for_inferior ();
1445
1446 target_terminal_init ();
1447 target_terminal_inferior ();
1448
1449 while (1)
1450 {
1451 stop_after_trap = 1;
1452 wait_for_inferior ();
1453 if (stop_signal != TARGET_SIGNAL_TRAP)
1454 resume (0, stop_signal);
1455 else
1456 break;
1457 }
1458 stop_after_trap = 0;
1459 return;
1460}
1461
02cc9f49
CV
1462/* Since Windows XP, detaching from a process is supported by Windows.
1463 The following code tries loading the appropriate functions dynamically.
1464 If loading these functions succeeds use them to actually detach from
1465 the inferior process, otherwise behave as usual, pretending that
1466 detach has worked. */
1467static BOOL WINAPI (*DebugSetProcessKillOnExit)(BOOL);
1468static BOOL WINAPI (*DebugActiveProcessStop)(DWORD);
1469
1470static int
5ae5f592 1471has_detach_ability (void)
02cc9f49
CV
1472{
1473 static HMODULE kernel32 = NULL;
1474
1475 if (!kernel32)
1476 kernel32 = LoadLibrary ("kernel32.dll");
1477 if (kernel32)
1478 {
1479 if (!DebugSetProcessKillOnExit)
1480 DebugSetProcessKillOnExit = GetProcAddress (kernel32,
1481 "DebugSetProcessKillOnExit");
1482 if (!DebugActiveProcessStop)
1483 DebugActiveProcessStop = GetProcAddress (kernel32,
1484 "DebugActiveProcessStop");
1485 if (DebugSetProcessKillOnExit && DebugActiveProcessStop)
1486 return 1;
1487 }
1488 return 0;
1489}
24e60978 1490
616a9dc4
CV
1491/* Try to set or remove a user privilege to the current process. Return -1
1492 if that fails, the previous setting of that privilege otherwise.
1493
1494 This code is copied from the Cygwin source code and rearranged to allow
1495 dynamically loading of the needed symbols from advapi32 which is only
1496 available on NT/2K/XP. */
1497static int
1498set_process_privilege (const char *privilege, BOOL enable)
1499{
1500 static HMODULE advapi32 = NULL;
1501 static BOOL WINAPI (*OpenProcessToken)(HANDLE, DWORD, PHANDLE);
1502 static BOOL WINAPI (*LookupPrivilegeValue)(LPCSTR, LPCSTR, PLUID);
1503 static BOOL WINAPI (*AdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES,
1504 DWORD, PTOKEN_PRIVILEGES, PDWORD);
1505
1506 HANDLE token_hdl = NULL;
1507 LUID restore_priv;
1508 TOKEN_PRIVILEGES new_priv, orig_priv;
1509 int ret = -1;
1510 DWORD size;
1511
1512 if (GetVersion () >= 0x80000000) /* No security availbale on 9x/Me */
1513 return 0;
1514
1515 if (!advapi32)
1516 {
1517 if (!(advapi32 = LoadLibrary ("advapi32.dll")))
1518 goto out;
1519 if (!OpenProcessToken)
1520 OpenProcessToken = GetProcAddress (advapi32, "OpenProcessToken");
1521 if (!LookupPrivilegeValue)
1522 LookupPrivilegeValue = GetProcAddress (advapi32,
1523 "LookupPrivilegeValueA");
1524 if (!AdjustTokenPrivileges)
1525 AdjustTokenPrivileges = GetProcAddress (advapi32,
1526 "AdjustTokenPrivileges");
1527 if (!OpenProcessToken || !LookupPrivilegeValue || !AdjustTokenPrivileges)
295732ea 1528 {
616a9dc4
CV
1529 advapi32 = NULL;
1530 goto out;
1531 }
1532 }
295732ea 1533
616a9dc4
CV
1534 if (!OpenProcessToken (GetCurrentProcess (),
1535 TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
1536 &token_hdl))
1537 goto out;
1538
1539 if (!LookupPrivilegeValue (NULL, privilege, &restore_priv))
1540 goto out;
1541
1542 new_priv.PrivilegeCount = 1;
1543 new_priv.Privileges[0].Luid = restore_priv;
1544 new_priv.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
1545
1546 if (!AdjustTokenPrivileges (token_hdl, FALSE, &new_priv,
295732ea 1547 sizeof orig_priv, &orig_priv, &size))
616a9dc4
CV
1548 goto out;
1549#if 0
1550 /* Disabled, otherwise every `attach' in an unprivileged user session
1551 would raise the "Failed to get SE_DEBUG_NAME privilege" warning in
3ee6f623 1552 win32_attach(). */
616a9dc4
CV
1553 /* AdjustTokenPrivileges returns TRUE even if the privilege could not
1554 be enabled. GetLastError () returns an correct error code, though. */
1555 if (enable && GetLastError () == ERROR_NOT_ALL_ASSIGNED)
1556 goto out;
1557#endif
1558
1559 ret = orig_priv.Privileges[0].Attributes == SE_PRIVILEGE_ENABLED ? 1 : 0;
1560
1561out:
1562 if (token_hdl)
1563 CloseHandle (token_hdl);
1564
1565 return ret;
1566}
1567
02cc9f49 1568/* Attach to process PID, then initialize for debugging it. */
24e60978 1569static void
3ee6f623 1570win32_attach (char *args, int from_tty)
24e60978
SC
1571{
1572 BOOL ok;
559e75c0 1573 DWORD pid;
24e60978
SC
1574
1575 if (!args)
e2e0b3e5 1576 error_no_arg (_("process-id to attach"));
24e60978 1577
616a9dc4
CV
1578 if (set_process_privilege (SE_DEBUG_NAME, TRUE) < 0)
1579 {
1580 printf_unfiltered ("Warning: Failed to get SE_DEBUG_NAME privilege\n");
1581 printf_unfiltered ("This can cause attach to fail on Windows NT/2K/XP\n");
1582 }
1583
baa93fa6
CF
1584 pid = strtoul (args, 0, 0); /* Windows pid */
1585
3ee6f623 1586 win32_init_thread_list ();
9d3789f7 1587 ok = DebugActiveProcess (pid);
91a175b3 1588 saw_create = 0;
24e60978
SC
1589
1590 if (!ok)
baa93fa6
CF
1591 {
1592 /* Try fall back to Cygwin pid */
1593 pid = cygwin_internal (CW_CYGWIN_PID_TO_WINPID, pid);
1594
1595 if (pid > 0)
1596 ok = DebugActiveProcess (pid);
1597
1598 if (!ok)
8a3fe4f8 1599 error (_("Can't attach to process."));
baa93fa6 1600 }
24e60978 1601
02cc9f49 1602 if (has_detach_ability ())
3ade5333
CF
1603 DebugSetProcessKillOnExit (FALSE);
1604
1605 attach_flag = 1;
02cc9f49 1606
24e60978
SC
1607 if (from_tty)
1608 {
1609 char *exec_file = (char *) get_exec_file (0);
1610
1611 if (exec_file)
1612 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
39f77062 1613 target_pid_to_str (pid_to_ptid (pid)));
24e60978
SC
1614 else
1615 printf_unfiltered ("Attaching to %s\n",
39f77062 1616 target_pid_to_str (pid_to_ptid (pid)));
24e60978
SC
1617
1618 gdb_flush (gdb_stdout);
1619 }
1620
3ee6f623 1621 do_initial_win32_stuff (pid);
9d3789f7 1622 target_terminal_ours ();
24e60978
SC
1623}
1624
24e60978 1625static void
3ee6f623 1626win32_detach (char *args, int from_tty)
24e60978 1627{
02cc9f49
CV
1628 int detached = 1;
1629
1630 if (has_detach_ability ())
1631 {
1632 delete_command (NULL, 0);
3ee6f623 1633 win32_continue (DBG_CONTINUE, -1);
02cc9f49 1634 if (!DebugActiveProcessStop (current_event.dwProcessId))
3bccec63 1635 {
8a3fe4f8 1636 error (_("Can't detach process %lu (error %lu)"),
02cc9f49
CV
1637 current_event.dwProcessId, GetLastError ());
1638 detached = 0;
3bccec63 1639 }
02cc9f49
CV
1640 DebugSetProcessKillOnExit (FALSE);
1641 }
1642 if (detached && from_tty)
24e60978
SC
1643 {
1644 char *exec_file = get_exec_file (0);
1645 if (exec_file == 0)
1646 exec_file = "";
02cc9f49
CV
1647 printf_unfiltered ("Detaching from program: %s, Pid %lu\n", exec_file,
1648 current_event.dwProcessId);
24e60978
SC
1649 gdb_flush (gdb_stdout);
1650 }
39f77062 1651 inferior_ptid = null_ptid;
3ee6f623 1652 unpush_target (&win32_ops);
24e60978
SC
1653}
1654
3ee6f623
CF
1655static char *
1656win32_pid_to_exec_file (int pid)
47216e51
CV
1657{
1658 /* Try to find the process path using the Cygwin internal process list
1659 pid isn't a valid pid, unfortunately. Use current_event.dwProcessId
1660 instead. */
1661 /* TODO: Also find native Windows processes using CW_GETPINFO_FULL. */
1662
1663 static char path[MAX_PATH + 1];
1664 char *path_ptr = NULL;
1665 int cpid;
1666 struct external_pinfo *pinfo;
1667
1668 cygwin_internal (CW_LOCK_PINFO, 1000);
1669 for (cpid = 0;
1670 (pinfo = (struct external_pinfo *)
3cb8e7f6 1671 cygwin_internal (CW_GETPINFO, cpid | CW_NEXTPID));
47216e51
CV
1672 cpid = pinfo->pid)
1673 {
1674 if (pinfo->dwProcessId == current_event.dwProcessId) /* Got it */
1675 {
3cb8e7f6
CF
1676 cygwin_conv_to_full_posix_path (pinfo->progname, path);
1677 path_ptr = path;
1678 break;
47216e51
CV
1679 }
1680 }
1681 cygwin_internal (CW_UNLOCK_PINFO);
3cb8e7f6 1682 return path_ptr;
47216e51
CV
1683}
1684
24e60978
SC
1685/* Print status information about what we're accessing. */
1686
1687static void
3ee6f623 1688win32_files_info (struct target_ops *ignore)
24e60978
SC
1689{
1690 printf_unfiltered ("\tUsing the running image of %s %s.\n",
39f77062 1691 attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid));
24e60978
SC
1692}
1693
24e60978 1694static void
3ee6f623 1695win32_open (char *arg, int from_tty)
24e60978 1696{
8a3fe4f8 1697 error (_("Use the \"run\" command to start a Unix child process."));
24e60978
SC
1698}
1699
8efc5725
CF
1700/* Function called by qsort to sort environment strings. */
1701static int
1702env_sort (const void *a, const void *b)
1703{
1704 const char **p = (const char **) a;
1705 const char **q = (const char **) b;
1706 return strcasecmp (*p, *q);
1707}
1708
39f77062 1709/* Start an inferior win32 child process and sets inferior_ptid to its pid.
24e60978
SC
1710 EXEC_FILE is the file to run.
1711 ALLARGS is a string containing the arguments to the program.
1712 ENV is the environment vector to pass. Errors reported with error(). */
1713
24e60978 1714static void
8efc5725 1715win32_create_inferior (char *exec_file, char *allargs, char **in_env,
c27cda74 1716 int from_tty)
24e60978 1717{
1750a5ef
SC
1718 char *winenv;
1719 char *temp;
3a4b77d8 1720 int envlen;
1750a5ef 1721 int i;
24e60978
SC
1722 STARTUPINFO si;
1723 PROCESS_INFORMATION pi;
24e60978
SC
1724 BOOL ret;
1725 DWORD flags;
eb708f2e 1726 char *args;
dfe7f3ac
CF
1727 char real_path[MAXPATHLEN];
1728 char *toexec;
349b409f
CF
1729 char shell[MAX_PATH + 1]; /* Path to shell */
1730 const char *sh;
2becadee
CF
1731 int tty;
1732 int ostdin, ostdout, ostderr;
3cb3b8df 1733 const char *inferior_io_terminal = get_inferior_io_terminal ();
24e60978
SC
1734
1735 if (!exec_file)
8a3fe4f8 1736 error (_("No executable specified, use `target exec'."));
24e60978
SC
1737
1738 memset (&si, 0, sizeof (si));
1739 si.cb = sizeof (si);
1740
349b409f 1741 if (!useshell)
dfe7f3ac
CF
1742 {
1743 flags = DEBUG_ONLY_THIS_PROCESS;
1744 cygwin_conv_to_win32_path (exec_file, real_path);
1745 toexec = real_path;
1746 }
1747 else
1748 {
349b409f
CF
1749 char *newallargs;
1750 sh = getenv ("SHELL");
1751 if (!sh)
1752 sh = "/bin/sh";
1753 cygwin_conv_to_win32_path (sh, shell);
1754 newallargs = alloca (sizeof (" -c 'exec '") + strlen (exec_file)
1755 + strlen (allargs) + 2);
dfe7f3ac
CF
1756 sprintf (newallargs, " -c 'exec %s %s'", exec_file, allargs);
1757 allargs = newallargs;
1758 toexec = shell;
1759 flags = DEBUG_PROCESS;
1760 }
eb708f2e 1761
eeb25b8a
PM
1762 if (new_group)
1763 flags |= CREATE_NEW_PROCESS_GROUP;
1764
1765 if (new_console)
1766 flags |= CREATE_NEW_CONSOLE;
1767
3ade5333
CF
1768 attach_flag = 0;
1769
dfe7f3ac
CF
1770 args = alloca (strlen (toexec) + strlen (allargs) + 2);
1771 strcpy (args, toexec);
eb708f2e
SC
1772 strcat (args, " ");
1773 strcat (args, allargs);
1774
e88c49c3
DE
1775 /* Prepare the environment vars for CreateProcess. */
1776 {
349b409f 1777 /* This code used to assume all env vars were file names and would
e88c49c3 1778 translate them all to win32 style. That obviously doesn't work in the
2dcfc9c7
DE
1779 general case. The current rule is that we only translate PATH.
1780 We need to handle PATH because we're about to call CreateProcess and
1781 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
1782 in both posix and win32 environments. cygwin.dll will change it back
1783 to posix style if necessary. */
e88c49c3
DE
1784
1785 static const char *conv_path_names[] =
3a4b77d8
JM
1786 {
1787 "PATH=",
1788 0
1789 };
e88c49c3
DE
1790
1791 /* CreateProcess takes the environment list as a null terminated set of
1792 strings (i.e. two nulls terminate the list). */
1793
1794 /* Get total size for env strings. */
8efc5725 1795 for (envlen = 0, i = 0; in_env[i] && *in_env[i]; i++)
e88c49c3 1796 {
2dcfc9c7 1797 int j, len;
e88c49c3 1798
2dcfc9c7
DE
1799 for (j = 0; conv_path_names[j]; j++)
1800 {
1801 len = strlen (conv_path_names[j]);
8efc5725 1802 if (strncmp (conv_path_names[j], in_env[i], len) == 0)
e88c49c3 1803 {
8efc5725 1804 if (cygwin_posix_path_list_p (in_env[i] + len))
2dcfc9c7 1805 envlen += len
8efc5725 1806 + cygwin_posix_to_win32_path_list_buf_size (in_env[i] + len);
2dcfc9c7 1807 else
8efc5725 1808 envlen += strlen (in_env[i]) + 1;
2dcfc9c7 1809 break;
e88c49c3 1810 }
e88c49c3 1811 }
2dcfc9c7 1812 if (conv_path_names[j] == NULL)
8efc5725 1813 envlen += strlen (in_env[i]) + 1;
e88c49c3
DE
1814 }
1815
8efc5725
CF
1816 size_t envsize = sizeof (in_env[0]) * (i + 1);
1817 char **env = (char **) alloca (envsize);
1818 memcpy (env, in_env, envsize);
1819 /* Windows programs expect the environment block to be sorted. */
1820 qsort (env, i, sizeof (char *), env_sort);
1821
e88c49c3
DE
1822 winenv = alloca (envlen + 1);
1823
1824 /* Copy env strings into new buffer. */
3cee93ac 1825 for (temp = winenv, i = 0; env[i] && *env[i]; i++)
e88c49c3 1826 {
2dcfc9c7 1827 int j, len;
e88c49c3 1828
2dcfc9c7
DE
1829 for (j = 0; conv_path_names[j]; j++)
1830 {
1831 len = strlen (conv_path_names[j]);
1832 if (strncmp (conv_path_names[j], env[i], len) == 0)
e88c49c3 1833 {
29fe111d 1834 if (cygwin_posix_path_list_p (env[i] + len))
e88c49c3
DE
1835 {
1836 memcpy (temp, env[i], len);
29fe111d 1837 cygwin_posix_to_win32_path_list (env[i] + len, temp + len);
e88c49c3 1838 }
2dcfc9c7
DE
1839 else
1840 strcpy (temp, env[i]);
1841 break;
e88c49c3 1842 }
e88c49c3 1843 }
2dcfc9c7 1844 if (conv_path_names[j] == NULL)
e88c49c3 1845 strcpy (temp, env[i]);
2dcfc9c7 1846
e88c49c3
DE
1847 temp += strlen (temp) + 1;
1848 }
1849
1850 /* Final nil string to terminate new env. */
1851 *temp = 0;
1852 }
1750a5ef 1853
2becadee
CF
1854 if (!inferior_io_terminal)
1855 tty = ostdin = ostdout = ostderr = -1;
1856 else
1857 {
1858 tty = open (inferior_io_terminal, O_RDWR | O_NOCTTY);
1859 if (tty < 0)
1860 {
1861 print_sys_errmsg (inferior_io_terminal, errno);
1862 ostdin = ostdout = ostderr = -1;
1863 }
1864 else
1865 {
1866 ostdin = dup (0);
1867 ostdout = dup (1);
1868 ostderr = dup (2);
1869 dup2 (tty, 0);
1870 dup2 (tty, 1);
1871 dup2 (tty, 2);
1872 }
1873 }
1874
3ee6f623 1875 win32_init_thread_list ();
1750a5ef 1876 ret = CreateProcess (0,
3a4b77d8 1877 args, /* command line */
24e60978
SC
1878 NULL, /* Security */
1879 NULL, /* thread */
1880 TRUE, /* inherit handles */
1881 flags, /* start flags */
1750a5ef 1882 winenv,
24e60978
SC
1883 NULL, /* current directory */
1884 &si,
1885 &pi);
2becadee
CF
1886 if (tty >= 0)
1887 {
1888 close (tty);
1889 dup2 (ostdin, 0);
1890 dup2 (ostdout, 1);
1891 dup2 (ostderr, 2);
1892 close (ostdin);
1893 close (ostdout);
1894 close (ostderr);
1895 }
1896
24e60978 1897 if (!ret)
8a3fe4f8
AC
1898 error (_("Error creating process %s, (error %d)."),
1899 exec_file, (unsigned) GetLastError ());
24e60978 1900
700b351b
CF
1901 CloseHandle (pi.hThread);
1902 CloseHandle (pi.hProcess);
dfe7f3ac
CF
1903
1904 if (useshell && shell[0] != '\0')
1905 saw_create = -1;
1906 else
1907 saw_create = 0;
1908
3ee6f623 1909 do_initial_win32_stuff (pi.dwProcessId);
d3a09475 1910
3ee6f623 1911 /* win32_continue (DBG_CONTINUE, -1); */
1e37c281 1912 proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
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 0.945713 seconds and 4 git commands to generate.