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