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