fix scrambled changelog
[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"
24e60978
SC
33#include "gdbcore.h"
34#include "command.h"
fa58ee11 35#include "completer.h"
4e052eda 36#include "regcache.h"
2a3d5645 37#include "top.h"
403d9909
CF
38#include <signal.h>
39#include <sys/types.h>
40#include <fcntl.h>
41#include <stdlib.h>
42#include <windows.h>
43#include <imagehlp.h>
44#include <sys/cygwin.h>
cad9cd60 45
24e60978 46#include "buildsym.h"
1ef980b9
SC
47#include "symfile.h"
48#include "objfiles.h"
24e60978 49#include "gdb_string.h"
fdfa3315 50#include "gdbthread.h"
24e60978 51#include "gdbcmd.h"
1750a5ef 52#include <sys/param.h>
1e37c281 53#include <unistd.h>
4646aa9d 54#include "exec.h"
24e60978 55
6c7de422
MK
56#include "i386-tdep.h"
57#include "i387-tdep.h"
58
0714f9bf
SS
59/* If we're not using the old Cygwin header file set, define the
60 following which never should have been in the generic Win32 API
61 headers in the first place since they were our own invention... */
62#ifndef _GNU_H_WINDOWS_H
9d3789f7 63enum
8e860359
CF
64 {
65 FLAG_TRACE_BIT = 0x100,
66 CONTEXT_DEBUGGER = (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
67 };
0714f9bf 68#endif
8e860359
CF
69#include <sys/procfs.h>
70#include <psapi.h>
0714f9bf 71
fa4ba8da
PM
72#define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \
73 | CONTEXT_EXTENDED_REGISTERS
97da3b20 74
fa4ba8da 75static unsigned dr[8];
87a45c96
CF
76static int debug_registers_changed;
77static int debug_registers_used;
97da3b20 78
3cee93ac
CF
79/* The string sent by cygwin when it processes a signal.
80 FIXME: This should be in a cygwin include file. */
81#define CYGWIN_SIGNAL_STRING "cygwin: signal"
82
29fe111d 83#define CHECK(x) check (x, __FILE__,__LINE__)
dfe7f3ac 84#define DEBUG_EXEC(x) if (debug_exec) printf_unfiltered x
4e52d31c
PM
85#define DEBUG_EVENTS(x) if (debug_events) printf_unfiltered x
86#define DEBUG_MEM(x) if (debug_memory) printf_unfiltered x
87#define DEBUG_EXCEPT(x) if (debug_exceptions) printf_unfiltered x
24e60978
SC
88
89/* Forward declaration */
90extern struct target_ops child_ops;
91
a14ed312 92static void child_stop (void);
39f77062 93static int win32_child_thread_alive (ptid_t);
a14ed312 94void child_kill_inferior (void);
3cee93ac 95
7393af7c
PM
96static enum target_signal last_sig = TARGET_SIGNAL_0;
97/* Set if a signal was received from the debugged process */
98
3cee93ac
CF
99/* Thread information structure used to track information that is
100 not available in gdb's thread structure. */
101typedef struct thread_info_struct
3a4b77d8
JM
102 {
103 struct thread_info_struct *next;
104 DWORD id;
105 HANDLE h;
106 char *name;
107 int suspend_count;
3ade5333 108 int reload_context;
3a4b77d8 109 CONTEXT context;
1e37c281 110 STACKFRAME sf;
8e860359
CF
111 }
112thread_info;
1e37c281 113
29fe111d 114static thread_info thread_head;
24e60978 115
24e60978
SC
116/* The process and thread handles for the above context. */
117
3cee93ac
CF
118static DEBUG_EVENT current_event; /* The current debug event from
119 WaitForDebugEvent */
120static HANDLE current_process_handle; /* Currently executing process */
121static thread_info *current_thread; /* Info on currently selected thread */
349b409f 122static DWORD main_thread_id; /* Thread ID of the main thread */
24e60978
SC
123
124/* Counts of things. */
125static int exception_count = 0;
126static int event_count = 0;
dfe7f3ac 127static int saw_create;
24e60978
SC
128
129/* User options. */
130static int new_console = 0;
1e37c281 131static int new_group = 1;
dfe7f3ac
CF
132static int debug_exec = 0; /* show execution */
133static int debug_events = 0; /* show events from kernel */
134static int debug_memory = 0; /* show target memory accesses */
1ef980b9 135static int debug_exceptions = 0; /* show target exceptions */
dfe7f3ac
CF
136static int useshell = 0; /* use shell for subprocesses */
137
24e60978 138/* This vector maps GDB's idea of a register's number into an address
3cee93ac 139 in the win32 exception context vector.
24e60978 140
3cee93ac 141 It also contains the bit mask needed to load the register in question.
24e60978
SC
142
143 One day we could read a reg, we could inspect the context we
144 already have loaded, if it doesn't have the bit set that we need,
145 we read that set of registers in using GetThreadContext. If the
146 context already contains what we need, we just unpack it. Then to
147 write a register, first we have to ensure that the context contains
148 the other regs of the group, and then we copy the info in and set
149 out bit. */
150
3cee93ac
CF
151#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
152static const int mappings[] =
24e60978 153{
3a4b77d8
JM
154 context_offset (Eax),
155 context_offset (Ecx),
156 context_offset (Edx),
157 context_offset (Ebx),
158 context_offset (Esp),
159 context_offset (Ebp),
160 context_offset (Esi),
161 context_offset (Edi),
162 context_offset (Eip),
163 context_offset (EFlags),
164 context_offset (SegCs),
165 context_offset (SegSs),
166 context_offset (SegDs),
167 context_offset (SegEs),
168 context_offset (SegFs),
169 context_offset (SegGs),
170 context_offset (FloatSave.RegisterArea[0 * 10]),
171 context_offset (FloatSave.RegisterArea[1 * 10]),
172 context_offset (FloatSave.RegisterArea[2 * 10]),
173 context_offset (FloatSave.RegisterArea[3 * 10]),
174 context_offset (FloatSave.RegisterArea[4 * 10]),
175 context_offset (FloatSave.RegisterArea[5 * 10]),
176 context_offset (FloatSave.RegisterArea[6 * 10]),
177 context_offset (FloatSave.RegisterArea[7 * 10]),
1e37c281
JM
178 context_offset (FloatSave.ControlWord),
179 context_offset (FloatSave.StatusWord),
180 context_offset (FloatSave.TagWord),
181 context_offset (FloatSave.ErrorSelector),
182 context_offset (FloatSave.ErrorOffset),
183 context_offset (FloatSave.DataSelector),
184 context_offset (FloatSave.DataOffset),
d3a09475 185 context_offset (FloatSave.ErrorSelector)
97da3b20 186 /* XMM0-7 */ ,
441532d7
PM
187 context_offset (ExtendedRegisters[10*16]),
188 context_offset (ExtendedRegisters[11*16]),
189 context_offset (ExtendedRegisters[12*16]),
190 context_offset (ExtendedRegisters[13*16]),
191 context_offset (ExtendedRegisters[14*16]),
192 context_offset (ExtendedRegisters[15*16]),
193 context_offset (ExtendedRegisters[16*16]),
194 context_offset (ExtendedRegisters[17*16]),
195 /* MXCSR */
196 context_offset (ExtendedRegisters[24])
24e60978
SC
197};
198
d3a09475
JM
199#undef context_offset
200
24e60978
SC
201/* This vector maps the target's idea of an exception (extracted
202 from the DEBUG_EVENT structure) to GDB's idea. */
203
204struct xlate_exception
205 {
206 int them;
207 enum target_signal us;
208 };
209
24e60978
SC
210static const struct xlate_exception
211 xlate[] =
212{
213 {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV},
9cbf6c0e 214 {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV},
24e60978
SC
215 {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP},
216 {DBG_CONTROL_C, TARGET_SIGNAL_INT},
217 {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP},
7393af7c 218 {STATUS_FLOAT_DIVIDE_BY_ZERO, TARGET_SIGNAL_FPE},
24e60978
SC
219 {-1, -1}};
220
fa4ba8da
PM
221static void
222check (BOOL ok, const char *file, int line)
223{
224 if (!ok)
dfe7f3ac 225 printf_filtered ("error return %s:%d was %lu\n", file, line,
fa4ba8da
PM
226 GetLastError ());
227}
228
3cee93ac
CF
229/* Find a thread record given a thread id.
230 If get_context then also retrieve the context for this
231 thread. */
232static thread_info *
233thread_rec (DWORD id, int get_context)
24e60978 234{
3cee93ac
CF
235 thread_info *th;
236
3a4b77d8 237 for (th = &thread_head; (th = th->next) != NULL;)
3cee93ac
CF
238 if (th->id == id)
239 {
240 if (!th->suspend_count && get_context)
241 {
8a892701 242 if (get_context > 0 && id != current_event.dwThreadId)
3cee93ac
CF
243 th->suspend_count = SuspendThread (th->h) + 1;
244 else if (get_context < 0)
245 th->suspend_count = -1;
3ade5333 246 th->reload_context = 1;
3cee93ac
CF
247 }
248 return th;
249 }
250
251 return NULL;
252}
253
254/* Add a thread to the thread list */
255static thread_info *
3a4b77d8 256child_add_thread (DWORD id, HANDLE h)
3cee93ac
CF
257{
258 thread_info *th;
259
260 if ((th = thread_rec (id, FALSE)))
261 return th;
262
263 th = (thread_info *) xmalloc (sizeof (*th));
3a4b77d8 264 memset (th, 0, sizeof (*th));
3cee93ac
CF
265 th->id = id;
266 th->h = h;
267 th->next = thread_head.next;
268 thread_head.next = th;
39f77062 269 add_thread (pid_to_ptid (id));
dfe7f3ac 270 /* Set the debug registers for the new thread in they are used. */
fa4ba8da
PM
271 if (debug_registers_used)
272 {
273 /* Only change the value of the debug registers. */
274 th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
275 CHECK (GetThreadContext (th->h, &th->context));
276 th->context.Dr0 = dr[0];
277 th->context.Dr1 = dr[1];
278 th->context.Dr2 = dr[2];
279 th->context.Dr3 = dr[3];
280 /* th->context.Dr6 = dr[6];
281 FIXME: should we set dr6 also ?? */
282 th->context.Dr7 = dr[7];
283 CHECK (SetThreadContext (th->h, &th->context));
284 th->context.ContextFlags = 0;
285 }
3cee93ac 286 return th;
24e60978
SC
287}
288
3cee93ac
CF
289/* Clear out any old thread list and reintialize it to a
290 pristine state. */
24e60978 291static void
fba45db2 292child_init_thread_list (void)
24e60978 293{
3cee93ac
CF
294 thread_info *th = &thread_head;
295
296 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
297 init_thread_list ();
298 while (th->next != NULL)
24e60978 299 {
3cee93ac
CF
300 thread_info *here = th->next;
301 th->next = here->next;
302 (void) CloseHandle (here->h);
b8c9b27d 303 xfree (here);
24e60978 304 }
3cee93ac
CF
305}
306
307/* Delete a thread from the list of threads */
308static void
309child_delete_thread (DWORD id)
310{
311 thread_info *th;
312
313 if (info_verbose)
39f77062
KB
314 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (pid_to_ptid (id)));
315 delete_thread (pid_to_ptid (id));
3cee93ac
CF
316
317 for (th = &thread_head;
318 th->next != NULL && th->next->id != id;
319 th = th->next)
320 continue;
321
322 if (th->next != NULL)
24e60978 323 {
3cee93ac
CF
324 thread_info *here = th->next;
325 th->next = here->next;
326 CloseHandle (here->h);
b8c9b27d 327 xfree (here);
24e60978
SC
328 }
329}
330
3cee93ac
CF
331static void
332do_child_fetch_inferior_registers (int r)
24e60978 333{
1e37c281
JM
334 char *context_offset = ((char *) &current_thread->context) + mappings[r];
335 long l;
6c7de422 336
3ade5333 337 if (!current_thread)
d6dc8049
CF
338 return; /* Windows sometimes uses a non-existent thread id in its
339 events */
3ade5333
CF
340
341 if (current_thread->reload_context)
342 {
343 thread_info *th = current_thread;
344 th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
345 GetThreadContext (th->h, &th->context);
346 /* Copy dr values from that thread. */
347 dr[0] = th->context.Dr0;
348 dr[1] = th->context.Dr1;
349 dr[2] = th->context.Dr2;
350 dr[3] = th->context.Dr3;
351 dr[6] = th->context.Dr6;
352 dr[7] = th->context.Dr7;
353 current_thread->reload_context = 0;
354 }
355
6c7de422
MK
356#define I387_ST0_REGNUM I386_ST0_REGNUM
357
358 if (r == I387_FISEG_REGNUM)
1e37c281 359 {
8e860359 360 l = *((long *) context_offset) & 0xffff;
1e37c281
JM
361 supply_register (r, (char *) &l);
362 }
6c7de422 363 else if (r == I387_FOP_REGNUM)
1e37c281 364 {
8e860359 365 l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
1e37c281
JM
366 supply_register (r, (char *) &l);
367 }
368 else if (r >= 0)
d3a09475 369 supply_register (r, context_offset);
3cee93ac 370 else
24e60978
SC
371 {
372 for (r = 0; r < NUM_REGS; r++)
3cee93ac 373 do_child_fetch_inferior_registers (r);
24e60978 374 }
6c7de422
MK
375
376#undef I387_ST0_REGNUM
3cee93ac
CF
377}
378
379static void
380child_fetch_inferior_registers (int r)
381{
39f77062 382 current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
d6dc8049
CF
383 /* Check if current_thread exists. Windows sometimes uses a non-existent
384 thread id in its events */
3ade5333
CF
385 if (current_thread)
386 do_child_fetch_inferior_registers (r);
3cee93ac
CF
387}
388
389static void
390do_child_store_inferior_registers (int r)
391{
3ade5333 392 if (!current_thread)
d6dc8049 393 /* Windows sometimes uses a non-existent thread id in its events */;
3ade5333 394 else if (r >= 0)
baa93fa6 395 regcache_collect (r, ((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)))
1e37c281
JM
481 error ("Can't get module info");
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)
5633f842 488 error ("Error getting dll name: %u\n", (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 }
721 error ("Error: dll starting at 0x%lx not found.\n", (DWORD) lpBaseOfDll);
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
CF
876 if (args == NULL)
877 error ("dll-symbols requires a file name");
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)
29fe111d 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;
1080 break;
1081 case STATUS_STACK_OVERFLOW:
1082 DEBUG_EXCEPTION_SIMPLE ("STATUS_STACK_OVERFLOW");
1ef980b9 1083 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
7393af7c
PM
1084 break;
1085 case STATUS_FLOAT_DENORMAL_OPERAND:
1086 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DENORMAL_OPERAND");
1087 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1088 break;
1089 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
1090 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ARRAY_BOUNDS_EXCEEDED");
1091 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1092 break;
1093 case STATUS_FLOAT_INEXACT_RESULT:
1094 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INEXACT_RESULT");
1095 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1096 break;
1097 case STATUS_FLOAT_INVALID_OPERATION:
1098 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_INVALID_OPERATION");
1099 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1100 break;
1101 case STATUS_FLOAT_OVERFLOW:
1102 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_OVERFLOW");
1103 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1104 break;
1105 case STATUS_FLOAT_STACK_CHECK:
1106 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_STACK_CHECK");
1107 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1ef980b9 1108 break;
3b7c8b74 1109 case STATUS_FLOAT_UNDERFLOW:
7393af7c
PM
1110 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
1111 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1112 break;
3b7c8b74 1113 case STATUS_FLOAT_DIVIDE_BY_ZERO:
7393af7c
PM
1114 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_DIVIDE_BY_ZERO");
1115 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1116 break;
3b7c8b74 1117 case STATUS_INTEGER_DIVIDE_BY_ZERO:
7393af7c 1118 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
3b7c8b74 1119 ourstatus->value.sig = TARGET_SIGNAL_FPE;
3b7c8b74 1120 break;
7393af7c
PM
1121 case STATUS_INTEGER_OVERFLOW:
1122 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
1123 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1ef980b9
SC
1124 break;
1125 case EXCEPTION_BREAKPOINT:
7393af7c 1126 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
1ef980b9
SC
1127 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1128 break;
1129 case DBG_CONTROL_C:
7393af7c 1130 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
1ef980b9 1131 ourstatus->value.sig = TARGET_SIGNAL_INT;
5b421780
PM
1132 break;
1133 case DBG_CONTROL_BREAK:
7393af7c 1134 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_BREAK");
5b421780 1135 ourstatus->value.sig = TARGET_SIGNAL_INT;
1ef980b9
SC
1136 break;
1137 case EXCEPTION_SINGLE_STEP:
7393af7c 1138 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
1ef980b9
SC
1139 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1140 break;
8227c82d 1141 case EXCEPTION_ILLEGAL_INSTRUCTION:
7393af7c
PM
1142 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_ILLEGAL_INSTRUCTION");
1143 ourstatus->value.sig = TARGET_SIGNAL_ILL;
1144 break;
1145 case EXCEPTION_PRIV_INSTRUCTION:
1146 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_PRIV_INSTRUCTION");
1147 ourstatus->value.sig = TARGET_SIGNAL_ILL;
1148 break;
1149 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
1150 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_NONCONTINUABLE_EXCEPTION");
8227c82d
CF
1151 ourstatus->value.sig = TARGET_SIGNAL_ILL;
1152 break;
1ef980b9 1153 default:
02e423b9
CF
1154 if (current_event.u.Exception.dwFirstChance)
1155 return 0;
29fe111d 1156 printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n",
3a4b77d8 1157 current_event.u.Exception.ExceptionRecord.ExceptionCode,
8e860359 1158 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress);
24e60978 1159 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
1ef980b9 1160 break;
24e60978 1161 }
24e60978 1162 exception_count++;
7393af7c 1163 last_sig = ourstatus->value.sig;
36339ecd 1164 return 1;
24e60978
SC
1165}
1166
3cee93ac
CF
1167/* Resume all artificially suspended threads if we are continuing
1168 execution */
1169static BOOL
8a892701 1170child_continue (DWORD continue_status, int id)
3cee93ac
CF
1171{
1172 int i;
1173 thread_info *th;
1174 BOOL res;
1175
7393af7c
PM
1176 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, %s);\n",
1177 current_event.dwProcessId, current_event.dwThreadId,
dfe7f3ac 1178 continue_status == DBG_CONTINUE ?
7393af7c 1179 "DBG_CONTINUE" : "DBG_EXCEPTION_NOT_HANDLED"));
0714f9bf
SS
1180 res = ContinueDebugEvent (current_event.dwProcessId,
1181 current_event.dwThreadId,
1182 continue_status);
1e37c281 1183 continue_status = 0;
0714f9bf 1184 if (res)
3a4b77d8 1185 for (th = &thread_head; (th = th->next) != NULL;)
29fe111d 1186 if (((id == -1) || (id == (int) th->id)) && th->suspend_count)
3cee93ac 1187 {
fa4ba8da 1188
3cee93ac
CF
1189 for (i = 0; i < th->suspend_count; i++)
1190 (void) ResumeThread (th->h);
1191 th->suspend_count = 0;
fa4ba8da
PM
1192 if (debug_registers_changed)
1193 {
3ade5333 1194 /* Only change the value of the debug registers */
fa4ba8da
PM
1195 th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
1196 th->context.Dr0 = dr[0];
1197 th->context.Dr1 = dr[1];
1198 th->context.Dr2 = dr[2];
1199 th->context.Dr3 = dr[3];
1200 /* th->context.Dr6 = dr[6];
dfe7f3ac 1201 FIXME: should we set dr6 also ?? */
fa4ba8da
PM
1202 th->context.Dr7 = dr[7];
1203 CHECK (SetThreadContext (th->h, &th->context));
1204 th->context.ContextFlags = 0;
1205 }
3cee93ac
CF
1206 }
1207
fa4ba8da 1208 debug_registers_changed = 0;
3cee93ac
CF
1209 return res;
1210}
1211
d6dc8049
CF
1212/* Called in pathological case where Windows fails to send a
1213 CREATE_PROCESS_DEBUG_EVENT after an attach. */
3ade5333 1214DWORD
5439edaa 1215fake_create_process (void)
3ade5333
CF
1216{
1217 current_process_handle = OpenProcess (PROCESS_ALL_ACCESS, FALSE,
1218 current_event.dwProcessId);
1219 main_thread_id = current_event.dwThreadId;
1220 current_thread = child_add_thread (main_thread_id,
1221 current_event.u.CreateThread.hThread);
1222 return main_thread_id;
1223}
1224
8a892701
CF
1225/* Get the next event from the child. Return 1 if the event requires
1226 handling by WFI (or whatever).
1227 */
1e37c281 1228static int
0a65a603 1229get_child_debug_event (int pid, struct target_waitstatus *ourstatus)
1e37c281
JM
1230{
1231 BOOL debug_event;
8a892701 1232 DWORD continue_status, event_code;
87a45c96 1233 thread_info *th;
8a892701 1234 static thread_info dummy_thread_info;
450005e7 1235 int retval = 0;
1e37c281 1236
7393af7c 1237 last_sig = TARGET_SIGNAL_0;
9d3789f7 1238
8a892701 1239 if (!(debug_event = WaitForDebugEvent (&current_event, 1000)))
29fe111d 1240 goto out;
1e37c281
JM
1241
1242 event_count++;
1243 continue_status = DBG_CONTINUE;
1e37c281 1244
8a892701 1245 event_code = current_event.dwDebugEventCode;
450005e7 1246 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
87a45c96 1247 th = NULL;
8a892701
CF
1248
1249 switch (event_code)
1e37c281
JM
1250 {
1251 case CREATE_THREAD_DEBUG_EVENT:
1252 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
8a892701
CF
1253 (unsigned) current_event.dwProcessId,
1254 (unsigned) current_event.dwThreadId,
1255 "CREATE_THREAD_DEBUG_EVENT"));
dfe7f3ac 1256 if (saw_create != 1)
3ade5333
CF
1257 {
1258 if (!saw_create && attach_flag)
1259 {
d6dc8049
CF
1260 /* Kludge around a Windows bug where first event is a create
1261 thread event. Caused when attached process does not have
1262 a main thread. */
3ade5333
CF
1263 retval = ourstatus->value.related_pid = fake_create_process ();
1264 saw_create++;
1265 }
1266 break;
1267 }
1e37c281 1268 /* Record the existence of this thread */
8a892701
CF
1269 th = child_add_thread (current_event.dwThreadId,
1270 current_event.u.CreateThread.hThread);
1e37c281
JM
1271 if (info_verbose)
1272 printf_unfiltered ("[New %s]\n",
39f77062
KB
1273 target_pid_to_str (
1274 pid_to_ptid (current_event.dwThreadId)));
450005e7 1275 retval = current_event.dwThreadId;
1e37c281
JM
1276 break;
1277
1278 case EXIT_THREAD_DEBUG_EVENT:
1279 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1280 (unsigned) current_event.dwProcessId,
1281 (unsigned) current_event.dwThreadId,
1282 "EXIT_THREAD_DEBUG_EVENT"));
87a45c96
CF
1283 if (current_event.dwThreadId != main_thread_id)
1284 {
1285 child_delete_thread (current_event.dwThreadId);
1286 th = &dummy_thread_info;
1287 }
1e37c281
JM
1288 break;
1289
1290 case CREATE_PROCESS_DEBUG_EVENT:
1291 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1292 (unsigned) current_event.dwProcessId,
1293 (unsigned) current_event.dwThreadId,
1294 "CREATE_PROCESS_DEBUG_EVENT"));
700b351b 1295 CloseHandle (current_event.u.CreateProcessInfo.hFile);
dfe7f3ac
CF
1296 if (++saw_create != 1)
1297 {
1298 CloseHandle (current_event.u.CreateProcessInfo.hProcess);
1299 break;
1300 }
1e37c281 1301
dfe7f3ac 1302 current_process_handle = current_event.u.CreateProcessInfo.hProcess;
87a45c96
CF
1303 if (main_thread_id)
1304 child_delete_thread (main_thread_id);
9d3789f7 1305 main_thread_id = current_event.dwThreadId;
1e37c281 1306 /* Add the main thread */
9d3789f7 1307 th = child_add_thread (main_thread_id,
8a892701 1308 current_event.u.CreateProcessInfo.hThread);
9d3789f7 1309 retval = ourstatus->value.related_pid = current_event.dwThreadId;
1e37c281
JM
1310 break;
1311
1312 case EXIT_PROCESS_DEBUG_EVENT:
1313 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1314 (unsigned) current_event.dwProcessId,
1315 (unsigned) current_event.dwThreadId,
1316 "EXIT_PROCESS_DEBUG_EVENT"));
dfe7f3ac
CF
1317 if (saw_create != 1)
1318 break;
1e37c281
JM
1319 ourstatus->kind = TARGET_WAITKIND_EXITED;
1320 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
1321 CloseHandle (current_process_handle);
9d3789f7 1322 retval = main_thread_id;
8a892701 1323 break;
1e37c281
JM
1324
1325 case LOAD_DLL_DEBUG_EVENT:
1326 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1327 (unsigned) current_event.dwProcessId,
1328 (unsigned) current_event.dwThreadId,
1329 "LOAD_DLL_DEBUG_EVENT"));
700b351b 1330 CloseHandle (current_event.u.LoadDll.hFile);
dfe7f3ac
CF
1331 if (saw_create != 1)
1332 break;
8a892701 1333 catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
1e37c281 1334 registers_changed (); /* mark all regs invalid */
450005e7
CF
1335 ourstatus->kind = TARGET_WAITKIND_LOADED;
1336 ourstatus->value.integer = 0;
9d3789f7 1337 retval = main_thread_id;
5633f842 1338 re_enable_breakpoints_in_shlibs ();
1e37c281
JM
1339 break;
1340
1341 case UNLOAD_DLL_DEBUG_EVENT:
1342 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1343 (unsigned) current_event.dwProcessId,
1344 (unsigned) current_event.dwThreadId,
1345 "UNLOAD_DLL_DEBUG_EVENT"));
dfe7f3ac
CF
1346 if (saw_create != 1)
1347 break;
d3ff4a77
CF
1348 catch_errors (handle_unload_dll, NULL, (char *) "", RETURN_MASK_ALL);
1349 registers_changed (); /* mark all regs invalid */
1350 /* ourstatus->kind = TARGET_WAITKIND_UNLOADED;
3bccec63 1351 does not exist yet. */
d3ff4a77 1352 break;
1e37c281
JM
1353
1354 case EXCEPTION_DEBUG_EVENT:
1355 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1356 (unsigned) current_event.dwProcessId,
1357 (unsigned) current_event.dwThreadId,
1358 "EXCEPTION_DEBUG_EVENT"));
dfe7f3ac
CF
1359 if (saw_create != 1)
1360 break;
02e423b9
CF
1361 if (handle_exception (ourstatus))
1362 retval = current_event.dwThreadId;
1e37c281
JM
1363 break;
1364
8a892701 1365 case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */
1e37c281 1366 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1367 (unsigned) current_event.dwProcessId,
1368 (unsigned) current_event.dwThreadId,
1369 "OUTPUT_DEBUG_STRING_EVENT"));
dfe7f3ac
CF
1370 if (saw_create != 1)
1371 break;
8e860359 1372 if (handle_output_debug_string (ourstatus))
9d3789f7 1373 retval = main_thread_id;
1e37c281 1374 break;
9d3789f7 1375
1e37c281 1376 default:
dfe7f3ac
CF
1377 if (saw_create != 1)
1378 break;
29fe111d
CF
1379 printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
1380 (DWORD) current_event.dwProcessId,
1381 (DWORD) current_event.dwThreadId);
1382 printf_unfiltered (" unknown event code %ld\n",
1e37c281
JM
1383 current_event.dwDebugEventCode);
1384 break;
1385 }
1386
dfe7f3ac 1387 if (!retval || saw_create != 1)
8a892701 1388 CHECK (child_continue (continue_status, -1));
450005e7 1389 else
9d3789f7 1390 {
39f77062 1391 inferior_ptid = pid_to_ptid (retval);
3ade5333 1392 current_thread = th ?: thread_rec (current_event.dwThreadId, TRUE);
9d3789f7 1393 }
1e37c281
JM
1394
1395out:
450005e7 1396 return retval;
1e37c281
JM
1397}
1398
1e37c281 1399/* Wait for interesting events to occur in the target process. */
39f77062
KB
1400static ptid_t
1401child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
24e60978 1402{
39f77062
KB
1403 int pid = PIDGET (ptid);
1404
24e60978
SC
1405 /* We loop when we get a non-standard exception rather than return
1406 with a SPURIOUS because resume can try and step or modify things,
3cee93ac 1407 which needs a current_thread->h. But some of these exceptions mark
24e60978
SC
1408 the birth or death of threads, which mean that the current thread
1409 isn't necessarily what you think it is. */
1410
1411 while (1)
450005e7
CF
1412 {
1413 int retval = get_child_debug_event (pid, ourstatus);
1414 if (retval)
39f77062 1415 return pid_to_ptid (retval);
450005e7
CF
1416 else
1417 {
1418 int detach = 0;
3cee93ac 1419
98bbd631
AC
1420 if (deprecated_ui_loop_hook != NULL)
1421 detach = deprecated_ui_loop_hook (0);
0714f9bf 1422
450005e7
CF
1423 if (detach)
1424 child_kill_inferior ();
1425 }
1426 }
24e60978
SC
1427}
1428
9d3789f7
CF
1429static void
1430do_initial_child_stuff (DWORD pid)
1431{
1432 extern int stop_after_trap;
fa4ba8da 1433 int i;
9d3789f7 1434
7393af7c 1435 last_sig = TARGET_SIGNAL_0;
9d3789f7
CF
1436 event_count = 0;
1437 exception_count = 0;
fa4ba8da 1438 debug_registers_changed = 0;
dfe7f3ac 1439 debug_registers_used = 0;
fa4ba8da
PM
1440 for (i = 0; i < sizeof (dr) / sizeof (dr[0]); i++)
1441 dr[i] = 0;
9d3789f7
CF
1442 current_event.dwProcessId = pid;
1443 memset (&current_event, 0, sizeof (current_event));
1444 push_target (&child_ops);
1445 child_init_thread_list ();
5633f842 1446 disable_breakpoints_in_shlibs (1);
9d3789f7
CF
1447 child_clear_solibs ();
1448 clear_proceed_status ();
1449 init_wait_for_inferior ();
1450
1451 target_terminal_init ();
1452 target_terminal_inferior ();
1453
1454 while (1)
1455 {
1456 stop_after_trap = 1;
1457 wait_for_inferior ();
1458 if (stop_signal != TARGET_SIGNAL_TRAP)
1459 resume (0, stop_signal);
1460 else
1461 break;
1462 }
1463 stop_after_trap = 0;
1464 return;
1465}
1466
02cc9f49
CV
1467/* Since Windows XP, detaching from a process is supported by Windows.
1468 The following code tries loading the appropriate functions dynamically.
1469 If loading these functions succeeds use them to actually detach from
1470 the inferior process, otherwise behave as usual, pretending that
1471 detach has worked. */
1472static BOOL WINAPI (*DebugSetProcessKillOnExit)(BOOL);
1473static BOOL WINAPI (*DebugActiveProcessStop)(DWORD);
1474
1475static int
5ae5f592 1476has_detach_ability (void)
02cc9f49
CV
1477{
1478 static HMODULE kernel32 = NULL;
1479
1480 if (!kernel32)
1481 kernel32 = LoadLibrary ("kernel32.dll");
1482 if (kernel32)
1483 {
1484 if (!DebugSetProcessKillOnExit)
1485 DebugSetProcessKillOnExit = GetProcAddress (kernel32,
1486 "DebugSetProcessKillOnExit");
1487 if (!DebugActiveProcessStop)
1488 DebugActiveProcessStop = GetProcAddress (kernel32,
1489 "DebugActiveProcessStop");
1490 if (DebugSetProcessKillOnExit && DebugActiveProcessStop)
1491 return 1;
1492 }
1493 return 0;
1494}
24e60978 1495
616a9dc4
CV
1496/* Try to set or remove a user privilege to the current process. Return -1
1497 if that fails, the previous setting of that privilege otherwise.
1498
1499 This code is copied from the Cygwin source code and rearranged to allow
1500 dynamically loading of the needed symbols from advapi32 which is only
1501 available on NT/2K/XP. */
1502static int
1503set_process_privilege (const char *privilege, BOOL enable)
1504{
1505 static HMODULE advapi32 = NULL;
1506 static BOOL WINAPI (*OpenProcessToken)(HANDLE, DWORD, PHANDLE);
1507 static BOOL WINAPI (*LookupPrivilegeValue)(LPCSTR, LPCSTR, PLUID);
1508 static BOOL WINAPI (*AdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES,
1509 DWORD, PTOKEN_PRIVILEGES, PDWORD);
1510
1511 HANDLE token_hdl = NULL;
1512 LUID restore_priv;
1513 TOKEN_PRIVILEGES new_priv, orig_priv;
1514 int ret = -1;
1515 DWORD size;
1516
1517 if (GetVersion () >= 0x80000000) /* No security availbale on 9x/Me */
1518 return 0;
1519
1520 if (!advapi32)
1521 {
1522 if (!(advapi32 = LoadLibrary ("advapi32.dll")))
1523 goto out;
1524 if (!OpenProcessToken)
1525 OpenProcessToken = GetProcAddress (advapi32, "OpenProcessToken");
1526 if (!LookupPrivilegeValue)
1527 LookupPrivilegeValue = GetProcAddress (advapi32,
1528 "LookupPrivilegeValueA");
1529 if (!AdjustTokenPrivileges)
1530 AdjustTokenPrivileges = GetProcAddress (advapi32,
1531 "AdjustTokenPrivileges");
1532 if (!OpenProcessToken || !LookupPrivilegeValue || !AdjustTokenPrivileges)
295732ea 1533 {
616a9dc4
CV
1534 advapi32 = NULL;
1535 goto out;
1536 }
1537 }
295732ea 1538
616a9dc4
CV
1539 if (!OpenProcessToken (GetCurrentProcess (),
1540 TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
1541 &token_hdl))
1542 goto out;
1543
1544 if (!LookupPrivilegeValue (NULL, privilege, &restore_priv))
1545 goto out;
1546
1547 new_priv.PrivilegeCount = 1;
1548 new_priv.Privileges[0].Luid = restore_priv;
1549 new_priv.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
1550
1551 if (!AdjustTokenPrivileges (token_hdl, FALSE, &new_priv,
295732ea 1552 sizeof orig_priv, &orig_priv, &size))
616a9dc4
CV
1553 goto out;
1554#if 0
1555 /* Disabled, otherwise every `attach' in an unprivileged user session
1556 would raise the "Failed to get SE_DEBUG_NAME privilege" warning in
1557 child_attach(). */
1558 /* AdjustTokenPrivileges returns TRUE even if the privilege could not
1559 be enabled. GetLastError () returns an correct error code, though. */
1560 if (enable && GetLastError () == ERROR_NOT_ALL_ASSIGNED)
1561 goto out;
1562#endif
1563
1564 ret = orig_priv.Privileges[0].Attributes == SE_PRIVILEGE_ENABLED ? 1 : 0;
1565
1566out:
1567 if (token_hdl)
1568 CloseHandle (token_hdl);
1569
1570 return ret;
1571}
1572
02cc9f49 1573/* Attach to process PID, then initialize for debugging it. */
24e60978 1574static void
fba45db2 1575child_attach (char *args, int from_tty)
24e60978
SC
1576{
1577 BOOL ok;
559e75c0 1578 DWORD pid;
24e60978
SC
1579
1580 if (!args)
1581 error_no_arg ("process-id to attach");
1582
616a9dc4
CV
1583 if (set_process_privilege (SE_DEBUG_NAME, TRUE) < 0)
1584 {
1585 printf_unfiltered ("Warning: Failed to get SE_DEBUG_NAME privilege\n");
1586 printf_unfiltered ("This can cause attach to fail on Windows NT/2K/XP\n");
1587 }
1588
baa93fa6
CF
1589 pid = strtoul (args, 0, 0); /* Windows pid */
1590
9d3789f7 1591 ok = DebugActiveProcess (pid);
91a175b3 1592 saw_create = 0;
24e60978
SC
1593
1594 if (!ok)
baa93fa6
CF
1595 {
1596 /* Try fall back to Cygwin pid */
1597 pid = cygwin_internal (CW_CYGWIN_PID_TO_WINPID, pid);
1598
1599 if (pid > 0)
1600 ok = DebugActiveProcess (pid);
1601
1602 if (!ok)
caad7706 1603 error ("Can't attach to process.");
baa93fa6 1604 }
24e60978 1605
02cc9f49 1606 if (has_detach_ability ())
3ade5333
CF
1607 DebugSetProcessKillOnExit (FALSE);
1608
1609 attach_flag = 1;
02cc9f49 1610
24e60978
SC
1611 if (from_tty)
1612 {
1613 char *exec_file = (char *) get_exec_file (0);
1614
1615 if (exec_file)
1616 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
39f77062 1617 target_pid_to_str (pid_to_ptid (pid)));
24e60978
SC
1618 else
1619 printf_unfiltered ("Attaching to %s\n",
39f77062 1620 target_pid_to_str (pid_to_ptid (pid)));
24e60978
SC
1621
1622 gdb_flush (gdb_stdout);
1623 }
1624
9d3789f7
CF
1625 do_initial_child_stuff (pid);
1626 target_terminal_ours ();
24e60978
SC
1627}
1628
24e60978 1629static void
0a65a603 1630child_detach (char *args, int from_tty)
24e60978 1631{
02cc9f49
CV
1632 int detached = 1;
1633
1634 if (has_detach_ability ())
1635 {
1636 delete_command (NULL, 0);
1637 child_continue (DBG_CONTINUE, -1);
1638 if (!DebugActiveProcessStop (current_event.dwProcessId))
3bccec63 1639 {
02cc9f49
CV
1640 error ("Can't detach process %lu (error %lu)",
1641 current_event.dwProcessId, GetLastError ());
1642 detached = 0;
3bccec63 1643 }
02cc9f49
CV
1644 DebugSetProcessKillOnExit (FALSE);
1645 }
1646 if (detached && from_tty)
24e60978
SC
1647 {
1648 char *exec_file = get_exec_file (0);
1649 if (exec_file == 0)
1650 exec_file = "";
02cc9f49
CV
1651 printf_unfiltered ("Detaching from program: %s, Pid %lu\n", exec_file,
1652 current_event.dwProcessId);
24e60978
SC
1653 gdb_flush (gdb_stdout);
1654 }
39f77062 1655 inferior_ptid = null_ptid;
24e60978
SC
1656 unpush_target (&child_ops);
1657}
1658
24e60978
SC
1659/* Print status information about what we're accessing. */
1660
1661static void
0a65a603 1662child_files_info (struct target_ops *ignore)
24e60978
SC
1663{
1664 printf_unfiltered ("\tUsing the running image of %s %s.\n",
39f77062 1665 attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid));
24e60978
SC
1666}
1667
24e60978 1668static void
0a65a603 1669child_open (char *arg, int from_tty)
24e60978
SC
1670{
1671 error ("Use the \"run\" command to start a Unix child process.");
1672}
1673
39f77062 1674/* Start an inferior win32 child process and sets inferior_ptid to its pid.
24e60978
SC
1675 EXEC_FILE is the file to run.
1676 ALLARGS is a string containing the arguments to the program.
1677 ENV is the environment vector to pass. Errors reported with error(). */
1678
24e60978 1679static void
c27cda74
AC
1680child_create_inferior (char *exec_file, char *allargs, char **env,
1681 int from_tty)
24e60978 1682{
1750a5ef
SC
1683 char *winenv;
1684 char *temp;
3a4b77d8 1685 int envlen;
1750a5ef 1686 int i;
24e60978
SC
1687 STARTUPINFO si;
1688 PROCESS_INFORMATION pi;
24e60978
SC
1689 BOOL ret;
1690 DWORD flags;
eb708f2e 1691 char *args;
dfe7f3ac
CF
1692 char real_path[MAXPATHLEN];
1693 char *toexec;
349b409f
CF
1694 char shell[MAX_PATH + 1]; /* Path to shell */
1695 const char *sh;
2becadee
CF
1696 int tty;
1697 int ostdin, ostdout, ostderr;
24e60978
SC
1698
1699 if (!exec_file)
450005e7 1700 error ("No executable specified, use `target exec'.\n");
24e60978
SC
1701
1702 memset (&si, 0, sizeof (si));
1703 si.cb = sizeof (si);
1704
349b409f 1705 if (!useshell)
dfe7f3ac
CF
1706 {
1707 flags = DEBUG_ONLY_THIS_PROCESS;
1708 cygwin_conv_to_win32_path (exec_file, real_path);
1709 toexec = real_path;
1710 }
1711 else
1712 {
349b409f
CF
1713 char *newallargs;
1714 sh = getenv ("SHELL");
1715 if (!sh)
1716 sh = "/bin/sh";
1717 cygwin_conv_to_win32_path (sh, shell);
1718 newallargs = alloca (sizeof (" -c 'exec '") + strlen (exec_file)
1719 + strlen (allargs) + 2);
dfe7f3ac
CF
1720 sprintf (newallargs, " -c 'exec %s %s'", exec_file, allargs);
1721 allargs = newallargs;
1722 toexec = shell;
1723 flags = DEBUG_PROCESS;
1724 }
eb708f2e 1725
eeb25b8a
PM
1726 if (new_group)
1727 flags |= CREATE_NEW_PROCESS_GROUP;
1728
1729 if (new_console)
1730 flags |= CREATE_NEW_CONSOLE;
1731
3ade5333
CF
1732 attach_flag = 0;
1733
dfe7f3ac
CF
1734 args = alloca (strlen (toexec) + strlen (allargs) + 2);
1735 strcpy (args, toexec);
eb708f2e
SC
1736 strcat (args, " ");
1737 strcat (args, allargs);
1738
e88c49c3
DE
1739 /* Prepare the environment vars for CreateProcess. */
1740 {
349b409f 1741 /* This code used to assume all env vars were file names and would
e88c49c3 1742 translate them all to win32 style. That obviously doesn't work in the
2dcfc9c7
DE
1743 general case. The current rule is that we only translate PATH.
1744 We need to handle PATH because we're about to call CreateProcess and
1745 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
1746 in both posix and win32 environments. cygwin.dll will change it back
1747 to posix style if necessary. */
e88c49c3
DE
1748
1749 static const char *conv_path_names[] =
3a4b77d8
JM
1750 {
1751 "PATH=",
1752 0
1753 };
e88c49c3
DE
1754
1755 /* CreateProcess takes the environment list as a null terminated set of
1756 strings (i.e. two nulls terminate the list). */
1757
1758 /* Get total size for env strings. */
1759 for (envlen = 0, i = 0; env[i] && *env[i]; i++)
1760 {
2dcfc9c7 1761 int j, len;
e88c49c3 1762
2dcfc9c7
DE
1763 for (j = 0; conv_path_names[j]; j++)
1764 {
1765 len = strlen (conv_path_names[j]);
1766 if (strncmp (conv_path_names[j], env[i], len) == 0)
e88c49c3 1767 {
29fe111d 1768 if (cygwin_posix_path_list_p (env[i] + len))
2dcfc9c7 1769 envlen += len
29fe111d 1770 + cygwin_posix_to_win32_path_list_buf_size (env[i] + len);
2dcfc9c7
DE
1771 else
1772 envlen += strlen (env[i]) + 1;
1773 break;
e88c49c3 1774 }
e88c49c3 1775 }
2dcfc9c7 1776 if (conv_path_names[j] == NULL)
e88c49c3
DE
1777 envlen += strlen (env[i]) + 1;
1778 }
1779
1780 winenv = alloca (envlen + 1);
1781
1782 /* Copy env strings into new buffer. */
3cee93ac 1783 for (temp = winenv, i = 0; env[i] && *env[i]; i++)
e88c49c3 1784 {
2dcfc9c7 1785 int j, len;
e88c49c3 1786
2dcfc9c7
DE
1787 for (j = 0; conv_path_names[j]; j++)
1788 {
1789 len = strlen (conv_path_names[j]);
1790 if (strncmp (conv_path_names[j], env[i], len) == 0)
e88c49c3 1791 {
29fe111d 1792 if (cygwin_posix_path_list_p (env[i] + len))
e88c49c3
DE
1793 {
1794 memcpy (temp, env[i], len);
29fe111d 1795 cygwin_posix_to_win32_path_list (env[i] + len, temp + len);
e88c49c3 1796 }
2dcfc9c7
DE
1797 else
1798 strcpy (temp, env[i]);
1799 break;
e88c49c3 1800 }
e88c49c3 1801 }
2dcfc9c7 1802 if (conv_path_names[j] == NULL)
e88c49c3 1803 strcpy (temp, env[i]);
2dcfc9c7 1804
e88c49c3
DE
1805 temp += strlen (temp) + 1;
1806 }
1807
1808 /* Final nil string to terminate new env. */
1809 *temp = 0;
1810 }
1750a5ef 1811
2becadee
CF
1812 if (!inferior_io_terminal)
1813 tty = ostdin = ostdout = ostderr = -1;
1814 else
1815 {
1816 tty = open (inferior_io_terminal, O_RDWR | O_NOCTTY);
1817 if (tty < 0)
1818 {
1819 print_sys_errmsg (inferior_io_terminal, errno);
1820 ostdin = ostdout = ostderr = -1;
1821 }
1822 else
1823 {
1824 ostdin = dup (0);
1825 ostdout = dup (1);
1826 ostderr = dup (2);
1827 dup2 (tty, 0);
1828 dup2 (tty, 1);
1829 dup2 (tty, 2);
1830 }
1831 }
1832
1750a5ef 1833 ret = CreateProcess (0,
3a4b77d8 1834 args, /* command line */
24e60978
SC
1835 NULL, /* Security */
1836 NULL, /* thread */
1837 TRUE, /* inherit handles */
1838 flags, /* start flags */
1750a5ef 1839 winenv,
24e60978
SC
1840 NULL, /* current directory */
1841 &si,
1842 &pi);
2becadee
CF
1843 if (tty >= 0)
1844 {
1845 close (tty);
1846 dup2 (ostdin, 0);
1847 dup2 (ostdout, 1);
1848 dup2 (ostderr, 2);
1849 close (ostdin);
1850 close (ostdout);
1851 close (ostderr);
1852 }
1853
24e60978 1854 if (!ret)
5633f842 1855 error ("Error creating process %s, (error %d)\n", exec_file, (unsigned) GetLastError ());
24e60978 1856
700b351b
CF
1857 CloseHandle (pi.hThread);
1858 CloseHandle (pi.hProcess);
dfe7f3ac
CF
1859
1860 if (useshell && shell[0] != '\0')
1861 saw_create = -1;
1862 else
1863 saw_create = 0;
1864
9d3789f7 1865 do_initial_child_stuff (pi.dwProcessId);
d3a09475 1866
8e860359 1867 /* child_continue (DBG_CONTINUE, -1); */
1e37c281 1868 proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
24e60978
SC
1869}
1870
1871static void
fba45db2 1872child_mourn_inferior (void)
24e60978 1873{
8a892701 1874 (void) child_continue (DBG_CONTINUE, -1);
fa4ba8da 1875 i386_cleanup_dregs();
24e60978
SC
1876 unpush_target (&child_ops);
1877 generic_mourn_inferior ();
1878}
1879
24e60978
SC
1880/* Send a SIGINT to the process group. This acts just like the user typed a
1881 ^C on the controlling terminal. */
1882
b607efe7 1883static void
fba45db2 1884child_stop (void)
24e60978 1885{
1ef980b9 1886 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
1e37c281 1887 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
3a4b77d8 1888 registers_changed (); /* refresh register state */
24e60978
SC
1889}
1890
1891int
eb708f2e 1892child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
0a65a603
AC
1893 int write, struct mem_attrib *mem,
1894 struct target_ops *target)
24e60978 1895{
6f17862b 1896 DWORD done = 0;
24e60978
SC
1897 if (write)
1898 {
29fe111d
CF
1899 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
1900 len, (DWORD) memaddr));
6f17862b
CF
1901 if (!WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our,
1902 len, &done))
1903 done = 0;
3cee93ac 1904 FlushInstructionCache (current_process_handle, (LPCVOID) memaddr, len);
24e60978
SC
1905 }
1906 else
1907 {
29fe111d
CF
1908 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
1909 len, (DWORD) memaddr));
6f17862b
CF
1910 if (!ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our,
1911 len, &done))
1912 done = 0;
24e60978
SC
1913 }
1914 return done;
1915}
1916
1917void
1918child_kill_inferior (void)
1919{
3cee93ac
CF
1920 CHECK (TerminateProcess (current_process_handle, 0));
1921
b5edcb45
ILT
1922 for (;;)
1923 {
8a892701 1924 if (!child_continue (DBG_CONTINUE, -1))
b5edcb45 1925 break;
3cee93ac 1926 if (!WaitForDebugEvent (&current_event, INFINITE))
b5edcb45 1927 break;
3cee93ac 1928 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
b5edcb45
ILT
1929 break;
1930 }
1931
3cee93ac
CF
1932 CHECK (CloseHandle (current_process_handle));
1933
1934 /* this may fail in an attached process so don't check. */
3ade5333
CF
1935 if (current_thread && current_thread->h)
1936 (void) CloseHandle (current_thread->h);
3a4b77d8 1937 target_mourn_inferior (); /* or just child_mourn_inferior? */
24e60978
SC
1938}
1939
1940void
39f77062 1941child_resume (ptid_t ptid, int step, enum target_signal sig)
24e60978 1942{
3cee93ac 1943 thread_info *th;
7393af7c
PM
1944 DWORD continue_status = DBG_CONTINUE;
1945
39f77062 1946 int pid = PIDGET (ptid);
8a892701 1947
7393af7c
PM
1948 if (sig != TARGET_SIGNAL_0)
1949 {
1950 if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
1951 {
1952 DEBUG_EXCEPT(("Cannot continue with signal %d here.\n",sig));
1953 }
1954 else if (sig == last_sig)
1955 continue_status = DBG_EXCEPTION_NOT_HANDLED;
1956 else
1957#if 0
1958/* This code does not seem to work, because
1959 the kernel does probably not consider changes in the ExceptionRecord
dfe7f3ac 1960 structure when passing the exception to the inferior.
7393af7c
PM
1961 Note that this seems possible in the exception handler itself. */
1962 {
1963 int i;
1964 for (i = 0; xlate[i].them != -1; i++)
1965 if (xlate[i].us == sig)
1966 {
1967 current_event.u.Exception.ExceptionRecord.ExceptionCode =
1968 xlate[i].them;
1969 continue_status = DBG_EXCEPTION_NOT_HANDLED;
1970 break;
1971 }
1972 if (continue_status == DBG_CONTINUE)
1973 {
1974 DEBUG_EXCEPT(("Cannot continue with signal %d.\n",sig));
1975 }
1976 }
1977#endif
dfe7f3ac 1978 DEBUG_EXCEPT(("Can only continue with recieved signal %d.\n",
7393af7c
PM
1979 last_sig));
1980 }
1981
1982 last_sig = TARGET_SIGNAL_0;
24e60978 1983
3cee93ac
CF
1984 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1985 pid, step, sig));
1986
1987 /* Get context for currently selected thread */
1988 th = thread_rec (current_event.dwThreadId, FALSE);
450005e7 1989 if (th)
24e60978 1990 {
450005e7
CF
1991 if (step)
1992 {
1993 /* Single step by setting t bit */
1994 child_fetch_inferior_registers (PS_REGNUM);
1995 th->context.EFlags |= FLAG_TRACE_BIT;
1996 }
24e60978 1997
450005e7
CF
1998 if (th->context.ContextFlags)
1999 {
caad7706
CF
2000 if (debug_registers_changed)
2001 {
2002 th->context.Dr0 = dr[0];
2003 th->context.Dr1 = dr[1];
2004 th->context.Dr2 = dr[2];
2005 th->context.Dr3 = dr[3];
2006 /* th->context.Dr6 = dr[6];
2007 FIXME: should we set dr6 also ?? */
2008 th->context.Dr7 = dr[7];
2009 }
450005e7
CF
2010 CHECK (SetThreadContext (th->h, &th->context));
2011 th->context.ContextFlags = 0;
2012 }
24e60978
SC
2013 }
2014
3cee93ac
CF
2015 /* Allow continuing with the same signal that interrupted us.
2016 Otherwise complain. */
24e60978 2017
8a892701 2018 child_continue (continue_status, pid);
24e60978
SC
2019}
2020
2021static void
fba45db2 2022child_prepare_to_store (void)
24e60978
SC
2023{
2024 /* Do nothing, since we can store individual regs */
2025}
2026
2027static int
fba45db2 2028child_can_run (void)
24e60978
SC
2029{
2030 return 1;
2031}
2032
2033static void
0a65a603 2034child_close (int x)
24e60978 2035{
39f77062 2036 DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n",
3bccec63 2037 PIDGET (inferior_ptid)));
24e60978 2038}
1ef980b9 2039
3a4b77d8 2040struct target_ops child_ops;
c719b714 2041
3a4b77d8
JM
2042static void
2043init_child_ops (void)
24e60978 2044{
3a4b77d8
JM
2045 child_ops.to_shortname = "child";
2046 child_ops.to_longname = "Win32 child process";
2047 child_ops.to_doc = "Win32 child process (started by the \"run\" command).";
2048 child_ops.to_open = child_open;
2049 child_ops.to_close = child_close;
2050 child_ops.to_attach = child_attach;
2051 child_ops.to_detach = child_detach;
2052 child_ops.to_resume = child_resume;
2053 child_ops.to_wait = child_wait;
2054 child_ops.to_fetch_registers = child_fetch_inferior_registers;
2055 child_ops.to_store_registers = child_store_inferior_registers;
2056 child_ops.to_prepare_to_store = child_prepare_to_store;
2057 child_ops.to_xfer_memory = child_xfer_memory;
2058 child_ops.to_files_info = child_files_info;
2059 child_ops.to_insert_breakpoint = memory_insert_breakpoint;
2060 child_ops.to_remove_breakpoint = memory_remove_breakpoint;
2061 child_ops.to_terminal_init = terminal_init_inferior;
2062 child_ops.to_terminal_inferior = terminal_inferior;
2063 child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
2064 child_ops.to_terminal_ours = terminal_ours;
a790ad35 2065 child_ops.to_terminal_save_ours = terminal_save_ours;
3a4b77d8
JM
2066 child_ops.to_terminal_info = child_terminal_info;
2067 child_ops.to_kill = child_kill_inferior;
3a4b77d8
JM
2068 child_ops.to_create_inferior = child_create_inferior;
2069 child_ops.to_mourn_inferior = child_mourn_inferior;
2070 child_ops.to_can_run = child_can_run;
3a4b77d8 2071 child_ops.to_thread_alive = win32_child_thread_alive;
d3a09475 2072 child_ops.to_pid_to_str = cygwin_pid_to_str;
3a4b77d8
JM
2073 child_ops.to_stop = child_stop;
2074 child_ops.to_stratum = process_stratum;
3a4b77d8
JM
2075 child_ops.to_has_all_memory = 1;
2076 child_ops.to_has_memory = 1;
2077 child_ops.to_has_stack = 1;
2078 child_ops.to_has_registers = 1;
2079 child_ops.to_has_execution = 1;
3a4b77d8 2080 child_ops.to_magic = OPS_MAGIC;
c719b714 2081}
24e60978
SC
2082
2083void
a6b6b089 2084_initialize_win32_nat (void)
24e60978 2085{
fa58ee11
EZ
2086 struct cmd_list_element *c;
2087
3a4b77d8 2088 init_child_ops ();
1ef980b9 2089
fa58ee11
EZ
2090 c = add_com ("dll-symbols", class_files, dll_symbol_command,
2091 "Load dll library symbols from FILE.");
5ba2abeb 2092 set_cmd_completer (c, filename_completer);
450005e7
CF
2093
2094 add_com_alias ("sharedlibrary", "dll-symbols", class_alias, 1);
2095
dfe7f3ac
CF
2096 add_show_from_set (add_set_cmd ("shell", class_support, var_boolean,
2097 (char *) &useshell,
2098 "Set use of shell to start subprocess.",
2099 &setlist),
2100 &showlist);
2101
450005e7 2102 add_show_from_set (add_set_cmd ("new-console", class_support, var_boolean,
8e860359
CF
2103 (char *) &new_console,
2104 "Set creation of new console when creating child process.",
2105 &setlist),
2106 &showlist);
24e60978 2107
450005e7 2108 add_show_from_set (add_set_cmd ("new-group", class_support, var_boolean,
8e860359
CF
2109 (char *) &new_group,
2110 "Set creation of new group when creating child process.",
2111 &setlist),
2112 &showlist);
24e60978 2113
450005e7 2114 add_show_from_set (add_set_cmd ("debugexec", class_support, var_boolean,
8e860359
CF
2115 (char *) &debug_exec,
2116 "Set whether to display execution in child process.",
2117 &setlist),
2118 &showlist);
1ef980b9 2119
450005e7 2120 add_show_from_set (add_set_cmd ("debugevents", class_support, var_boolean,
8e860359
CF
2121 (char *) &debug_events,
2122 "Set whether to display kernel events in child process.",
2123 &setlist),
2124 &showlist);
1ef980b9 2125
450005e7 2126 add_show_from_set (add_set_cmd ("debugmemory", class_support, var_boolean,
8e860359
CF
2127 (char *) &debug_memory,
2128 "Set whether to display memory accesses in child process.",
2129 &setlist),
2130 &showlist);
1ef980b9 2131
450005e7 2132 add_show_from_set (add_set_cmd ("debugexceptions", class_support, var_boolean,
8e860359
CF
2133 (char *) &debug_exceptions,
2134 "Set whether to display kernel exceptions in child process.",
2135 &setlist),
2136 &showlist);
1ef980b9 2137
450005e7
CF
2138 add_info ("dll", info_dll_command, "Status of loaded DLLs.");
2139 add_info_alias ("sharedlibrary", "dll", 1);
2140
c1748f97 2141 add_prefix_cmd ("w32", class_info, info_w32_command,
baa93fa6
CF
2142 "Print information specific to Win32 debugging.",
2143 &info_w32_cmdlist, "info w32 ", 0, &infolist);
c1748f97
PM
2144
2145 add_cmd ("selector", class_info, display_selectors,
baa93fa6 2146 "Display selectors infos.",
c1748f97
PM
2147 &info_w32_cmdlist);
2148
24e60978
SC
2149 add_target (&child_ops);
2150}
3cee93ac 2151
fa4ba8da
PM
2152/* Hardware watchpoint support, adapted from go32-nat.c code. */
2153
2154/* Pass the address ADDR to the inferior in the I'th debug register.
2155 Here we just store the address in dr array, the registers will be
2156 actually set up when child_continue is called. */
2157void
2158cygwin_set_dr (int i, CORE_ADDR addr)
2159{
2160 if (i < 0 || i > 3)
2161 internal_error (__FILE__, __LINE__,
2162 "Invalid register %d in cygwin_set_dr.\n", i);
2163 dr[i] = (unsigned) addr;
2164 debug_registers_changed = 1;
2165 debug_registers_used = 1;
2166}
2167
2168/* Pass the value VAL to the inferior in the DR7 debug control
2169 register. Here we just store the address in D_REGS, the watchpoint
2170 will be actually set up in child_wait. */
2171void
2172cygwin_set_dr7 (unsigned val)
2173{
2174 dr[7] = val;
2175 debug_registers_changed = 1;
2176 debug_registers_used = 1;
2177}
2178
2179/* Get the value of the DR6 debug status register from the inferior.
2180 Here we just return the value stored in dr[6]
2181 by the last call to thread_rec for current_event.dwThreadId id. */
2182unsigned
2183cygwin_get_dr6 (void)
2184{
2185 return dr[6];
2186}
2187
3cee93ac
CF
2188/* Determine if the thread referenced by "pid" is alive
2189 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
2190 it means that the pid has died. Otherwise it is assumed to be alive. */
2191static int
39f77062 2192win32_child_thread_alive (ptid_t ptid)
3cee93ac 2193{
39f77062
KB
2194 int pid = PIDGET (ptid);
2195
3a4b77d8
JM
2196 return WaitForSingleObject (thread_rec (pid, FALSE)->h, 0) == WAIT_OBJECT_0 ?
2197 FALSE : TRUE;
3cee93ac
CF
2198}
2199
2200/* Convert pid to printable format. */
2201char *
39f77062 2202cygwin_pid_to_str (ptid_t ptid)
3cee93ac
CF
2203{
2204 static char buf[80];
39f77062
KB
2205 int pid = PIDGET (ptid);
2206
29fe111d 2207 if ((DWORD) pid == current_event.dwProcessId)
b69571f5 2208 sprintf (buf, "process %d", pid);
3cee93ac 2209 else
b69571f5 2210 sprintf (buf, "thread %ld.0x%x", current_event.dwProcessId, pid);
3cee93ac
CF
2211 return buf;
2212}
8e860359
CF
2213
2214static int
2215core_dll_symbols_add (char *dll_name, DWORD base_addr)
2216{
2217 struct objfile *objfile;
2218 char *objfile_basename;
2219 const char *dll_basename;
2220
2221 if (!(dll_basename = strrchr (dll_name, '/')))
2222 dll_basename = dll_name;
2223 else
2224 dll_basename++;
2225
2226 ALL_OBJFILES (objfile)
2227 {
2228 objfile_basename = strrchr (objfile->name, '/');
2229
2230 if (objfile_basename &&
2231 strcmp (dll_basename, objfile_basename + 1) == 0)
2232 {
2233 printf_unfiltered ("%08lx:%s (symbols previously loaded)\n",
2234 base_addr, dll_name);
2235 goto out;
2236 }
2237 }
2238
87a45c96
CF
2239 register_loaded_dll (dll_name, base_addr + 0x1000);
2240 solib_symbols_add (dll_name, 0, (CORE_ADDR) base_addr + 0x1000);
8e860359 2241
87a45c96
CF
2242 out:
2243 return 1;
2244 }
8e860359 2245
87a45c96
CF
2246 typedef struct
2247 {
2248 struct target_ops *target;
2249 bfd_vma addr;
2250 } map_code_section_args;
8e860359 2251
87a45c96
CF
2252 static void
2253 map_single_dll_code_section (bfd * abfd, asection * sect, void *obj)
2254 {
2255 int old;
2256 int update_coreops;
2257 struct section_table *new_target_sect_ptr;
8e860359 2258
87a45c96
CF
2259 map_code_section_args *args = (map_code_section_args *) obj;
2260 struct target_ops *target = args->target;
2261 if (sect->flags & SEC_CODE)
2262 {
2263 update_coreops = core_ops.to_sections == target->to_sections;
8e860359 2264
87a45c96
CF
2265 if (target->to_sections)
2266 {
2267 old = target->to_sections_end - target->to_sections;
2268 target->to_sections = (struct section_table *)
2269 xrealloc ((char *) target->to_sections,
2270 (sizeof (struct section_table)) * (1 + old));
2271 }
2272 else
2273 {
2274 old = 0;
2275 target->to_sections = (struct section_table *)
2276 xmalloc ((sizeof (struct section_table)));
2277 }
2278 target->to_sections_end = target->to_sections + (1 + old);
8e860359 2279
87a45c96
CF
2280 /* Update the to_sections field in the core_ops structure
2281 if needed. */
2282 if (update_coreops)
2283 {
2284 core_ops.to_sections = target->to_sections;
2285 core_ops.to_sections_end = target->to_sections_end;
2286 }
2287 new_target_sect_ptr = target->to_sections + old;
2288 new_target_sect_ptr->addr = args->addr + bfd_section_vma (abfd, sect);
2289 new_target_sect_ptr->endaddr = args->addr + bfd_section_vma (abfd, sect) +
2290 bfd_section_size (abfd, sect);;
2291 new_target_sect_ptr->the_bfd_section = sect;
2292 new_target_sect_ptr->bfd = abfd;
2293 }
2294 }
8e860359 2295
87a45c96
CF
2296 static int
2297 dll_code_sections_add (const char *dll_name, int base_addr, struct target_ops *target)
8e860359
CF
2298{
2299 bfd *dll_bfd;
2300 map_code_section_args map_args;
2301 asection *lowest_sect;
2302 char *name;
2303 if (dll_name == NULL || target == NULL)
2304 return 0;
66ed1d85 2305 name = xstrdup (dll_name);
8e860359
CF
2306 dll_bfd = bfd_openr (name, "pei-i386");
2307 if (dll_bfd == NULL)
2308 return 0;
2309
2310 if (bfd_check_format (dll_bfd, bfd_object))
2311 {
2312 lowest_sect = bfd_get_section_by_name (dll_bfd, ".text");
2313 if (lowest_sect == NULL)
2314 return 0;
2315 map_args.target = target;
2316 map_args.addr = base_addr - bfd_section_vma (dll_bfd, lowest_sect);
2317
554cb486 2318 bfd_map_over_sections (dll_bfd, &map_single_dll_code_section, (void *) (&map_args));
8e860359
CF
2319 }
2320
2321 return 1;
2322}
2323
2324static void
554cb486 2325core_section_load_dll_symbols (bfd * abfd, asection * sect, void *obj)
8e860359
CF
2326{
2327 struct target_ops *target = (struct target_ops *) obj;
2328
2329 DWORD base_addr;
2330
2331 int dll_name_size;
2332 char *dll_name = NULL;
2333 char *buf = NULL;
2334 struct win32_pstatus *pstatus;
2335 char *p;
2336
2337 if (strncmp (sect->name, ".module", 7))
2338 return;
2339
2c500098 2340 buf = (char *) xmalloc (bfd_get_section_size (sect) + 1);
8e860359
CF
2341 if (!buf)
2342 {
2343 printf_unfiltered ("memory allocation failed for %s\n", sect->name);
2344 goto out;
2345 }
2c500098 2346 if (!bfd_get_section_contents (abfd, sect, buf, 0, bfd_get_section_size (sect)))
8e860359
CF
2347 goto out;
2348
2349 pstatus = (struct win32_pstatus *) buf;
2350
2351 memmove (&base_addr, &(pstatus->data.module_info.base_address), sizeof (base_addr));
2352 dll_name_size = pstatus->data.module_info.module_name_size;
2c500098 2353 if (offsetof (struct win32_pstatus, data.module_info.module_name) + dll_name_size > bfd_get_section_size (sect))
8e860359
CF
2354 goto out;
2355
2356 dll_name = (char *) xmalloc (dll_name_size + 1);
2357 if (!dll_name)
2358 {
2359 printf_unfiltered ("memory allocation failed for %s\n", sect->name);
2360 goto out;
2361 }
2362 strncpy (dll_name, pstatus->data.module_info.module_name, dll_name_size);
2363
2364 while ((p = strchr (dll_name, '\\')))
2365 *p = '/';
2366
2367 if (!core_dll_symbols_add (dll_name, (DWORD) base_addr))
2368 printf_unfiltered ("%s: Failed to load dll symbols.\n", dll_name);
2369
2370 if (!dll_code_sections_add (dll_name, (DWORD) base_addr + 0x1000, target))
2371 printf_unfiltered ("%s: Failed to map dll code sections.\n", dll_name);
2372
2373out:
2374 if (buf)
b8c9b27d 2375 xfree (buf);
8e860359 2376 if (dll_name)
b8c9b27d 2377 xfree (dll_name);
8e860359
CF
2378 return;
2379}
2380
2381void
0a65a603
AC
2382child_solib_add (char *filename, int from_tty, struct target_ops *target,
2383 int readsyms)
8e860359 2384{
990f9fe3
FF
2385 if (!readsyms)
2386 return;
8e860359
CF
2387 if (core_bfd)
2388 {
2389 child_clear_solibs ();
2390 bfd_map_over_sections (core_bfd, &core_section_load_dll_symbols, target);
2391 }
2392 else
2393 {
2394 if (solib_end && solib_end->name)
d3ff4a77 2395 solib_end->objfile = solib_symbols_add (solib_end->name, from_tty,
3bccec63 2396 solib_end->load_addr);
8e860359
CF
2397 }
2398}
2399
2400static void
2401fetch_elf_core_registers (char *core_reg_sect,
2402 unsigned core_reg_size,
2403 int which,
2404 CORE_ADDR reg_addr)
2405{
2406 int r;
2407 if (core_reg_size < sizeof (CONTEXT))
2408 {
2409 error ("Core file register section too small (%u bytes).", core_reg_size);
2410 return;
2411 }
2412 for (r = 0; r < NUM_REGS; r++)
2413 supply_register (r, core_reg_sect + mappings[r]);
2414}
2415
2416static struct core_fns win32_elf_core_fns =
2417{
2418 bfd_target_elf_flavour,
2419 default_check_format,
2420 default_core_sniffer,
2421 fetch_elf_core_registers,
2422 NULL
2423};
2424
2425void
0613c401 2426_initialize_core_win32 (void)
8e860359 2427{
00e32a35 2428 deprecated_add_core_fns (&win32_elf_core_fns);
8e860359 2429}
2a3d5645
CF
2430
2431void
2432_initialize_check_for_gdb_ini (void)
2433{
2434 char *homedir;
2435 if (inhibit_gdbinit)
2436 return;
2437
2438 homedir = getenv ("HOME");
2439 if (homedir)
2440 {
2441 char *p;
2442 char *oldini = (char *) alloca (strlen (homedir) +
2443 sizeof ("/gdb.ini"));
2444 strcpy (oldini, homedir);
2445 p = strchr (oldini, '\0');
2446 if (p > oldini && p[-1] != '/')
2447 *p++ = '/';
2448 strcpy (p, "gdb.ini");
2449 if (access (oldini, 0) == 0)
2450 {
2451 int len = strlen (oldini);
2452 char *newini = alloca (len + 1);
dfe7f3ac 2453 sprintf (newini, "%.*s.gdbinit",
58fa08f0 2454 (int) (len - (sizeof ("gdb.ini") - 1)), oldini);
2a3d5645
CF
2455 warning ("obsolete '%s' found. Rename to '%s'.", oldini, newini);
2456 }
2457 }
2458}
This page took 0.81228 seconds and 4 git commands to generate.