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