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