]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/win32-nat.c
* gdb.base/bigcore.c (main): Add missing mode argument in open
[thirdparty/binutils-gdb.git] / gdb / win32-nat.c
CommitLineData
c906108c 1/* Target-vector operations for controlling win32 child processes, for GDB.
0a65a603 2
059198c1 3 Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
2c500098 4 Free Software Foundation, Inc.
0a65a603 5
e6433c28 6 Contributed by Cygnus Solutions, A Red Hat Company.
c906108c
SS
7
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
c5aa993b 22 Foundation, Inc., 59 Temple Place - Suite 330,
4e052eda 23 Boston, MA 02111-1307, USA. */
c906108c 24
dfe7f3ac 25/* Originally by Steve Chamberlain, sac@cygnus.com */
c906108c
SS
26
27/* We assume we're being built with and will be used for cygwin. */
28
29#include "defs.h"
30#include "frame.h" /* required by inferior.h */
31#include "inferior.h"
32#include "target.h"
60250e8b 33#include "exceptions.h"
c906108c
SS
34#include "gdbcore.h"
35#include "command.h"
fa58ee11 36#include "completer.h"
4e052eda 37#include "regcache.h"
2a3d5645 38#include "top.h"
403d9909
CF
39#include <signal.h>
40#include <sys/types.h>
41#include <fcntl.h>
42#include <stdlib.h>
43#include <windows.h>
44#include <imagehlp.h>
45#include <sys/cygwin.h>
c906108c
SS
46
47#include "buildsym.h"
48#include "symfile.h"
49#include "objfiles.h"
50#include "gdb_string.h"
51#include "gdbthread.h"
52#include "gdbcmd.h"
53#include <sys/param.h>
c2d11a7d 54#include <unistd.h>
4646aa9d 55#include "exec.h"
c906108c 56
6c7de422
MK
57#include "i386-tdep.h"
58#include "i387-tdep.h"
59
7a292a7a
SS
60/* If we're not using the old Cygwin header file set, define the
61 following which never should have been in the generic Win32 API
62 headers in the first place since they were our own invention... */
63#ifndef _GNU_H_WINDOWS_H
9d3789f7 64enum
8e860359
CF
65 {
66 FLAG_TRACE_BIT = 0x100,
67 CONTEXT_DEBUGGER = (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
68 };
7a292a7a 69#endif
8e860359
CF
70#include <sys/procfs.h>
71#include <psapi.h>
7a292a7a 72
fa4ba8da
PM
73#define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_DEBUG_REGISTERS \
74 | CONTEXT_EXTENDED_REGISTERS
97da3b20 75
fa4ba8da 76static unsigned dr[8];
87a45c96
CF
77static int debug_registers_changed;
78static int debug_registers_used;
97da3b20 79
c906108c
SS
80/* The string sent by cygwin when it processes a signal.
81 FIXME: This should be in a cygwin include file. */
82#define CYGWIN_SIGNAL_STRING "cygwin: signal"
83
29fe111d 84#define CHECK(x) check (x, __FILE__,__LINE__)
dfe7f3ac 85#define DEBUG_EXEC(x) if (debug_exec) printf_unfiltered x
4e52d31c
PM
86#define DEBUG_EVENTS(x) if (debug_events) printf_unfiltered x
87#define DEBUG_MEM(x) if (debug_memory) printf_unfiltered x
88#define DEBUG_EXCEPT(x) if (debug_exceptions) printf_unfiltered x
c906108c 89
a14ed312 90static void child_stop (void);
39f77062 91static int win32_child_thread_alive (ptid_t);
a14ed312 92void child_kill_inferior (void);
c906108c 93
7393af7c
PM
94static enum target_signal last_sig = TARGET_SIGNAL_0;
95/* Set if a signal was received from the debugged process */
96
c906108c
SS
97/* Thread information structure used to track information that is
98 not available in gdb's thread structure. */
99typedef struct thread_info_struct
c5aa993b
JM
100 {
101 struct thread_info_struct *next;
102 DWORD id;
103 HANDLE h;
104 char *name;
105 int suspend_count;
3ade5333 106 int reload_context;
c5aa993b 107 CONTEXT context;
c2d11a7d 108 STACKFRAME sf;
8e860359
CF
109 }
110thread_info;
c2d11a7d 111
29fe111d 112static thread_info thread_head;
c906108c 113
c906108c
SS
114/* The process and thread handles for the above context. */
115
116static DEBUG_EVENT current_event; /* The current debug event from
117 WaitForDebugEvent */
118static HANDLE current_process_handle; /* Currently executing process */
119static thread_info *current_thread; /* Info on currently selected thread */
349b409f 120static DWORD main_thread_id; /* Thread ID of the main thread */
c906108c
SS
121
122/* Counts of things. */
123static int exception_count = 0;
124static int event_count = 0;
dfe7f3ac 125static int saw_create;
c906108c
SS
126
127/* User options. */
128static int new_console = 0;
c2d11a7d 129static int new_group = 1;
dfe7f3ac
CF
130static int debug_exec = 0; /* show execution */
131static int debug_events = 0; /* show events from kernel */
132static int debug_memory = 0; /* show target memory accesses */
c906108c 133static int debug_exceptions = 0; /* show target exceptions */
dfe7f3ac
CF
134static int useshell = 0; /* use shell for subprocesses */
135
c906108c
SS
136/* This vector maps GDB's idea of a register's number into an address
137 in the win32 exception context vector.
138
139 It also contains the bit mask needed to load the register in question.
140
141 One day we could read a reg, we could inspect the context we
142 already have loaded, if it doesn't have the bit set that we need,
143 we read that set of registers in using GetThreadContext. If the
144 context already contains what we need, we just unpack it. Then to
145 write a register, first we have to ensure that the context contains
146 the other regs of the group, and then we copy the info in and set
147 out bit. */
148
149#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
150static const int mappings[] =
151{
c5aa993b
JM
152 context_offset (Eax),
153 context_offset (Ecx),
154 context_offset (Edx),
155 context_offset (Ebx),
156 context_offset (Esp),
157 context_offset (Ebp),
158 context_offset (Esi),
159 context_offset (Edi),
160 context_offset (Eip),
161 context_offset (EFlags),
162 context_offset (SegCs),
163 context_offset (SegSs),
164 context_offset (SegDs),
165 context_offset (SegEs),
166 context_offset (SegFs),
167 context_offset (SegGs),
168 context_offset (FloatSave.RegisterArea[0 * 10]),
169 context_offset (FloatSave.RegisterArea[1 * 10]),
170 context_offset (FloatSave.RegisterArea[2 * 10]),
171 context_offset (FloatSave.RegisterArea[3 * 10]),
172 context_offset (FloatSave.RegisterArea[4 * 10]),
173 context_offset (FloatSave.RegisterArea[5 * 10]),
174 context_offset (FloatSave.RegisterArea[6 * 10]),
175 context_offset (FloatSave.RegisterArea[7 * 10]),
c2d11a7d
JM
176 context_offset (FloatSave.ControlWord),
177 context_offset (FloatSave.StatusWord),
178 context_offset (FloatSave.TagWord),
179 context_offset (FloatSave.ErrorSelector),
180 context_offset (FloatSave.ErrorOffset),
181 context_offset (FloatSave.DataSelector),
182 context_offset (FloatSave.DataOffset),
ed9a39eb 183 context_offset (FloatSave.ErrorSelector)
97da3b20 184 /* XMM0-7 */ ,
441532d7
PM
185 context_offset (ExtendedRegisters[10*16]),
186 context_offset (ExtendedRegisters[11*16]),
187 context_offset (ExtendedRegisters[12*16]),
188 context_offset (ExtendedRegisters[13*16]),
189 context_offset (ExtendedRegisters[14*16]),
190 context_offset (ExtendedRegisters[15*16]),
191 context_offset (ExtendedRegisters[16*16]),
192 context_offset (ExtendedRegisters[17*16]),
193 /* MXCSR */
194 context_offset (ExtendedRegisters[24])
c906108c
SS
195};
196
ed9a39eb
JM
197#undef context_offset
198
c906108c
SS
199/* This vector maps the target's idea of an exception (extracted
200 from the DEBUG_EVENT structure) to GDB's idea. */
201
202struct xlate_exception
203 {
204 int them;
205 enum target_signal us;
206 };
207
208static const struct xlate_exception
209 xlate[] =
210{
211 {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV},
212 {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV},
213 {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP},
214 {DBG_CONTROL_C, TARGET_SIGNAL_INT},
215 {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP},
7393af7c 216 {STATUS_FLOAT_DIVIDE_BY_ZERO, TARGET_SIGNAL_FPE},
c906108c
SS
217 {-1, -1}};
218
fa4ba8da
PM
219static void
220check (BOOL ok, const char *file, int line)
221{
222 if (!ok)
dfe7f3ac 223 printf_filtered ("error return %s:%d was %lu\n", file, line,
fa4ba8da
PM
224 GetLastError ());
225}
226
c906108c
SS
227/* Find a thread record given a thread id.
228 If get_context then also retrieve the context for this
229 thread. */
230static thread_info *
231thread_rec (DWORD id, int get_context)
232{
233 thread_info *th;
234
c5aa993b 235 for (th = &thread_head; (th = th->next) != NULL;)
c906108c
SS
236 if (th->id == id)
237 {
238 if (!th->suspend_count && get_context)
239 {
8a892701 240 if (get_context > 0 && id != current_event.dwThreadId)
c906108c
SS
241 th->suspend_count = SuspendThread (th->h) + 1;
242 else if (get_context < 0)
243 th->suspend_count = -1;
3ade5333 244 th->reload_context = 1;
c906108c
SS
245 }
246 return th;
247 }
248
249 return NULL;
250}
251
252/* Add a thread to the thread list */
253static thread_info *
c5aa993b 254child_add_thread (DWORD id, HANDLE h)
c906108c
SS
255{
256 thread_info *th;
257
258 if ((th = thread_rec (id, FALSE)))
259 return th;
260
261 th = (thread_info *) xmalloc (sizeof (*th));
c5aa993b 262 memset (th, 0, sizeof (*th));
c906108c
SS
263 th->id = id;
264 th->h = h;
265 th->next = thread_head.next;
266 thread_head.next = th;
39f77062 267 add_thread (pid_to_ptid (id));
dfe7f3ac 268 /* Set the debug registers for the new thread in they are used. */
fa4ba8da
PM
269 if (debug_registers_used)
270 {
271 /* Only change the value of the debug registers. */
272 th->context.ContextFlags = CONTEXT_DEBUG_REGISTERS;
273 CHECK (GetThreadContext (th->h, &th->context));
274 th->context.Dr0 = dr[0];
275 th->context.Dr1 = dr[1];
276 th->context.Dr2 = dr[2];
277 th->context.Dr3 = dr[3];
278 /* th->context.Dr6 = dr[6];
279 FIXME: should we set dr6 also ?? */
280 th->context.Dr7 = dr[7];
281 CHECK (SetThreadContext (th->h, &th->context));
282 th->context.ContextFlags = 0;
283 }
c906108c
SS
284 return th;
285}
286
287/* Clear out any old thread list and reintialize it to a
288 pristine state. */
289static void
fba45db2 290child_init_thread_list (void)
c906108c
SS
291{
292 thread_info *th = &thread_head;
293
294 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
295 init_thread_list ();
296 while (th->next != NULL)
297 {
298 thread_info *here = th->next;
299 th->next = here->next;
300 (void) CloseHandle (here->h);
b8c9b27d 301 xfree (here);
c906108c 302 }
059198c1 303 thread_head.next = NULL;
c906108c
SS
304}
305
306/* Delete a thread from the list of threads */
307static void
308child_delete_thread (DWORD id)
309{
310 thread_info *th;
311
312 if (info_verbose)
39f77062
KB
313 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (pid_to_ptid (id)));
314 delete_thread (pid_to_ptid (id));
c906108c
SS
315
316 for (th = &thread_head;
317 th->next != NULL && th->next->id != id;
318 th = th->next)
319 continue;
320
321 if (th->next != NULL)
322 {
323 thread_info *here = th->next;
324 th->next = here->next;
325 CloseHandle (here->h);
b8c9b27d 326 xfree (here);
c906108c
SS
327 }
328}
329
c906108c
SS
330static void
331do_child_fetch_inferior_registers (int r)
332{
c2d11a7d
JM
333 char *context_offset = ((char *) &current_thread->context) + mappings[r];
334 long l;
6c7de422 335
3ade5333 336 if (!current_thread)
d6dc8049
CF
337 return; /* Windows sometimes uses a non-existent thread id in its
338 events */
3ade5333
CF
339
340 if (current_thread->reload_context)
341 {
342 thread_info *th = current_thread;
343 th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
344 GetThreadContext (th->h, &th->context);
345 /* Copy dr values from that thread. */
346 dr[0] = th->context.Dr0;
347 dr[1] = th->context.Dr1;
348 dr[2] = th->context.Dr2;
349 dr[3] = th->context.Dr3;
350 dr[6] = th->context.Dr6;
351 dr[7] = th->context.Dr7;
352 current_thread->reload_context = 0;
353 }
354
6c7de422
MK
355#define I387_ST0_REGNUM I386_ST0_REGNUM
356
357 if (r == I387_FISEG_REGNUM)
c2d11a7d 358 {
8e860359 359 l = *((long *) context_offset) & 0xffff;
23a6d369 360 regcache_raw_supply (current_regcache, r, (char *) &l);
c2d11a7d 361 }
6c7de422 362 else if (r == I387_FOP_REGNUM)
c2d11a7d 363 {
8e860359 364 l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
23a6d369 365 regcache_raw_supply (current_regcache, r, (char *) &l);
c2d11a7d
JM
366 }
367 else if (r >= 0)
23a6d369 368 regcache_raw_supply (current_regcache, r, context_offset);
c906108c
SS
369 else
370 {
371 for (r = 0; r < NUM_REGS; r++)
372 do_child_fetch_inferior_registers (r);
373 }
6c7de422
MK
374
375#undef I387_ST0_REGNUM
c906108c
SS
376}
377
378static void
379child_fetch_inferior_registers (int r)
380{
39f77062 381 current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
d6dc8049
CF
382 /* Check if current_thread exists. Windows sometimes uses a non-existent
383 thread id in its events */
3ade5333
CF
384 if (current_thread)
385 do_child_fetch_inferior_registers (r);
c906108c
SS
386}
387
388static void
389do_child_store_inferior_registers (int r)
390{
3ade5333 391 if (!current_thread)
d6dc8049 392 /* Windows sometimes uses a non-existent thread id in its events */;
3ade5333 393 else if (r >= 0)
822c9732
AC
394 regcache_raw_collect (current_regcache, r,
395 ((char *) &current_thread->context) + mappings[r]);
c906108c
SS
396 else
397 {
398 for (r = 0; r < NUM_REGS; r++)
399 do_child_store_inferior_registers (r);
400 }
401}
402
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);
c906108c
SS
412}
413
c2d11a7d
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;
c2d11a7d 419
3bccec63 420int
8e860359 421psapi_get_dll_name (DWORD BaseAddress, char *dll_name_ret)
c2d11a7d
JM
422{
423 DWORD len;
424 MODULEINFO mi;
425 int i;
8e860359
CF
426 HMODULE dh_buf[1];
427 HMODULE *DllHandle = dh_buf;
c2d11a7d
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)
c2d11a7d 435 {
8e860359
CF
436 if (psapi_loaded)
437 goto failed;
c2d11a7d
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");
c2d11a7d
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)
c2d11a7d
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);
c2d11a7d
JM
460
461 if (!ok || !cbNeeded)
462 goto failed;
463
8e860359 464 DllHandle = (HMODULE *) alloca (cbNeeded);
c2d11a7d
JM
465 if (!DllHandle)
466 goto failed;
467
468 ok = (*psapi_EnumProcessModules) (current_process_handle,
8e860359
CF
469 DllHandle,
470 cbNeeded,
471 &cbNeeded);
c2d11a7d
JM
472 if (!ok)
473 goto failed;
474
29fe111d 475 for (i = 0; i < (int) (cbNeeded / sizeof (HMODULE)); i++)
c2d11a7d
JM
476 {
477 if (!(*psapi_GetModuleInformation) (current_process_handle,
8e860359
CF
478 DllHandle[i],
479 &mi,
480 sizeof (mi)))
8a3fe4f8 481 error (_("Can't get module info"));
c2d11a7d
JM
482
483 len = (*psapi_GetModuleFileNameExA) (current_process_handle,
8e860359
CF
484 DllHandle[i],
485 dll_name_ret,
486 MAX_PATH);
c2d11a7d 487 if (len == 0)
8a3fe4f8 488 error (_("Error getting dll name: %u."), (unsigned) GetLastError ());
c2d11a7d
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
c906108c
SS
676/* Wait for child to do something. Return pid of child, or -1 in case
677 of error; store status through argument pointer OURSTATUS. */
c906108c 678static int
0a65a603 679handle_load_dll (void *dummy)
c906108c 680{
c5aa993b 681 LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
c906108c 682 char dll_buf[MAX_PATH + 1];
450005e7 683 char *dll_name = NULL;
450005e7 684 char *p;
c906108c 685
c5aa993b 686 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
c906108c 687
c2d11a7d 688 if (!psapi_get_dll_name ((DWORD) (event->lpBaseOfDll), dll_buf))
8e860359 689 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
c906108c 690
c2d11a7d 691 dll_name = dll_buf;
c906108c 692
dfe7f3ac
CF
693 if (*dll_name == '\0')
694 dll_name = get_image_name (current_process_handle, event->lpImageName, event->fUnicode);
c906108c
SS
695 if (!dll_name)
696 return 1;
697
8e860359 698 register_loaded_dll (dll_name, (DWORD) event->lpBaseOfDll + 0x1000);
450005e7
CF
699
700 return 1;
701}
702
d3ff4a77 703static int
0a65a603 704handle_unload_dll (void *dummy)
d3ff4a77
CF
705{
706 DWORD lpBaseOfDll = (DWORD) current_event.u.UnloadDll.lpBaseOfDll + 0x1000;
707 struct so_stuff *so;
708
709 for (so = &solib_start; so->next != NULL; so = so->next)
710 if (so->next->load_addr == lpBaseOfDll)
711 {
712 struct so_stuff *sodel = so->next;
713 so->next = sodel->next;
714 if (!so->next)
715 solib_end = so;
716 if (sodel->objfile)
717 free_objfile (sodel->objfile);
718 xfree(sodel);
719 return 1;
720 }
8a3fe4f8 721 error (_("Error: dll starting at 0x%lx not found."), (DWORD) lpBaseOfDll);
d3ff4a77
CF
722
723 return 0;
724}
725
5633f842
CF
726char *
727solib_address (CORE_ADDR address)
728{
729 struct so_stuff *so;
730 for (so = &solib_start; so->next != NULL; so = so->next)
731 if (address >= so->load_addr && address <= so->end_addr)
732 return so->name;
733 return NULL;
734}
735
450005e7
CF
736/* Return name of last loaded DLL. */
737char *
0a65a603 738child_solib_loaded_library_pathname (int pid)
450005e7 739{
8e860359 740 return !solib_end || !solib_end->name[0] ? NULL : solib_end->name;
450005e7
CF
741}
742
743/* Clear list of loaded DLLs. */
744void
745child_clear_solibs (void)
746{
747 struct so_stuff *so, *so1 = solib_start.next;
748
749 while ((so = so1) != NULL)
750 {
751 so1 = so->next;
b8c9b27d 752 xfree (so);
450005e7
CF
753 }
754
755 solib_start.next = NULL;
d3ff4a77 756 solib_start.objfile = NULL;
450005e7
CF
757 solib_end = &solib_start;
758 max_dll_name_len = sizeof ("DLL Name") - 1;
759}
295732ea 760
786b8124
CF
761/* Get the loaded address of all sections, given that .text was loaded
762 at text_load. Assumes that all sections are subject to the same
763 relocation offset. Returns NULL if problems occur or if the
764 sections were not relocated. */
765
766static struct section_addr_info *
767get_relocated_section_addrs (bfd *abfd, CORE_ADDR text_load)
768{
769 struct section_addr_info *result = NULL;
770 int section_count = bfd_count_sections (abfd);
771 asection *text_section = bfd_get_section_by_name (abfd, ".text");
772 CORE_ADDR text_vma;
773
774 if (!text_section)
775 {
776 /* Couldn't get the .text section. Weird. */
777 }
778
779 else if (text_load == (text_vma = bfd_get_section_vma (abfd, text_section)))
780 {
781 /* DLL wasn't relocated. */
782 }
783
784 else
785 {
786 /* Figure out all sections' loaded addresses. The offset here is
787 such that taking a bfd_get_section_vma() result and adding
788 offset will give the real load address of the section. */
450005e7 789
786b8124
CF
790 CORE_ADDR offset = text_load - text_vma;
791
792 struct section_table *table_start = NULL;
793 struct section_table *table_end = NULL;
794 struct section_table *iter = NULL;
795
796 build_section_table (abfd, &table_start, &table_end);
797
798 for (iter = table_start; iter < table_end; ++iter)
799 {
800 /* Relocated addresses. */
801 iter->addr += offset;
802 iter->endaddr += offset;
803 }
804
805 result = build_section_addr_info_from_section_table (table_start,
806 table_end);
807
808 xfree (table_start);
809 }
810
811 return result;
812}
295732ea 813
450005e7 814/* Add DLL symbol information. */
d3ff4a77 815static struct objfile *
02e423b9 816solib_symbols_add (char *name, int from_tty, CORE_ADDR load_addr)
450005e7 817{
9f476a01 818 struct section_addr_info *addrs = NULL;
786b8124
CF
819 static struct objfile *result = NULL;
820 bfd *abfd = NULL;
450005e7 821
c906108c
SS
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. */
c906108c 825
8e860359 826 if (!name || !name[0])
d3ff4a77 827 return NULL;
450005e7 828
786b8124
CF
829 abfd = bfd_openr (name, "pei-i386");
830
831 if (!abfd)
832 {
833 /* pei failed - try pe */
834 abfd = bfd_openr (name, "pe-i386");
835 }
836
837 if (abfd)
838 {
839 if (bfd_check_format (abfd, bfd_object))
840 {
9f476a01 841 addrs = get_relocated_section_addrs (abfd, load_addr);
786b8124
CF
842 }
843
844 bfd_close (abfd);
845 }
846
9f476a01 847 if (addrs)
786b8124 848 {
9f476a01
CF
849 result = safe_symbol_file_add (name, from_tty, addrs, 0, OBJF_SHARED);
850 free_section_addr_info (addrs);
786b8124 851 }
786b8124
CF
852 else
853 {
854 /* Fallback on handling just the .text section. */
a39a16c4 855 struct cleanup *my_cleanups;
786b8124 856
9f476a01
CF
857 addrs = alloc_section_addr_info (1);
858 my_cleanups = make_cleanup (xfree, addrs);
859 addrs->other[0].name = ".text";
860 addrs->other[0].addr = load_addr;
786b8124 861
9f476a01 862 result = safe_symbol_file_add (name, from_tty, addrs, 0, OBJF_SHARED);
a39a16c4 863 do_cleanups (my_cleanups);
786b8124
CF
864 }
865
866 return result;
450005e7
CF
867}
868
869/* Load DLL symbol info. */
870void
7470a420 871dll_symbol_command (char *args, int from_tty)
450005e7 872{
8e860359 873 int n;
450005e7 874 dont_repeat ();
8e860359 875
450005e7 876 if (args == NULL)
8a3fe4f8 877 error (_("dll-symbols requires a file name"));
450005e7 878
8e860359
CF
879 n = strlen (args);
880 if (n > 4 && strcasecmp (args + n - 4, ".dll") != 0)
881 {
882 char *newargs = (char *) alloca (n + 4 + 1);
883 strcpy (newargs, args);
884 strcat (newargs, ".dll");
885 args = newargs;
886 }
887
7470a420 888 safe_symbol_file_add (args, from_tty, NULL, 0, OBJF_SHARED | OBJF_USERLOADED);
8e860359 889}
450005e7
CF
890
891/* List currently loaded DLLs. */
892void
0a65a603 893info_dll_command (char *ignore, int from_tty)
450005e7
CF
894{
895 struct so_stuff *so = &solib_start;
896
897 if (!so->next)
898 return;
899
dfe7f3ac 900 printf_filtered ("%*s Load Address\n", -max_dll_name_len, "DLL Name");
450005e7 901 while ((so = so->next) != NULL)
7c5c87c0 902 printf_filtered ("%*s %08lx\n", -max_dll_name_len, so->name, so->load_addr);
450005e7
CF
903
904 return;
c906108c
SS
905}
906
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
c5aa993b 917 ((CORE_ADDR) current_event.u.DebugString.lpDebugStringData, &s, 1024, 0)
c906108c
SS
918 || !s || !*s)
919 return gotasig;
920
ed9a39eb 921 if (strncmp (s, CYGWIN_SIGNAL_STRING, sizeof (CYGWIN_SIGNAL_STRING) - 1) != 0)
c906108c 922 {
ed9a39eb 923 if (strncmp (s, "cYg", 3) != 0)
8a3fe4f8 924 warning (("%s"), s);
c906108c 925 }
ed9a39eb 926 else
c906108c
SS
927 {
928 char *p;
c2d11a7d
JM
929 int sig = strtol (s + sizeof (CYGWIN_SIGNAL_STRING) - 1, &p, 0);
930 gotasig = target_signal_from_host (sig);
7a292a7a
SS
931 ourstatus->value.sig = gotasig;
932 if (gotasig)
c906108c
SS
933 ourstatus->kind = TARGET_WAITKIND_STOPPED;
934 }
935
b8c9b27d 936 xfree (s);
c906108c
SS
937 return gotasig;
938}
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
c906108c 1064static int
450005e7 1065handle_exception (struct target_waitstatus *ourstatus)
c906108c 1066{
c906108c 1067 thread_info *th;
29fe111d 1068 DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
c906108c 1069
29fe111d 1070 ourstatus->kind = TARGET_WAITKIND_STOPPED;
8a892701 1071
c906108c
SS
1072 /* Record the context of the current thread */
1073 th = thread_rec (current_event.dwThreadId, -1);
1074
29fe111d 1075 switch (code)
c906108c
SS
1076 {
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");
c906108c 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;
c906108c 1108 break;
0d06e24b 1109 case STATUS_FLOAT_UNDERFLOW:
7393af7c
PM
1110 DEBUG_EXCEPTION_SIMPLE ("STATUS_FLOAT_UNDERFLOW");
1111 ourstatus->value.sig = TARGET_SIGNAL_FPE;
1112 break;
0d06e24b 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;
0d06e24b 1117 case STATUS_INTEGER_DIVIDE_BY_ZERO:
7393af7c 1118 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_DIVIDE_BY_ZERO");
0d06e24b 1119 ourstatus->value.sig = TARGET_SIGNAL_FPE;
0d06e24b 1120 break;
7393af7c
PM
1121 case STATUS_INTEGER_OVERFLOW:
1122 DEBUG_EXCEPTION_SIMPLE ("STATUS_INTEGER_OVERFLOW");
1123 ourstatus->value.sig = TARGET_SIGNAL_FPE;
c906108c
SS
1124 break;
1125 case EXCEPTION_BREAKPOINT:
7393af7c 1126 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_BREAKPOINT");
c906108c
SS
1127 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
1128 break;
1129 case DBG_CONTROL_C:
7393af7c 1130 DEBUG_EXCEPTION_SIMPLE ("DBG_CONTROL_C");
c906108c 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;
c906108c
SS
1136 break;
1137 case EXCEPTION_SINGLE_STEP:
7393af7c 1138 DEBUG_EXCEPTION_SIMPLE ("EXCEPTION_SINGLE_STEP");
c906108c
SS
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;
c906108c 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",
c5aa993b 1157 current_event.u.Exception.ExceptionRecord.ExceptionCode,
8e860359 1158 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress);
c906108c
SS
1159 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
1160 break;
1161 }
1162 exception_count++;
7393af7c 1163 last_sig = ourstatus->value.sig;
c906108c
SS
1164 return 1;
1165}
1166
1167/* Resume all artificially suspended threads if we are continuing
1168 execution */
1169static BOOL
8a892701 1170child_continue (DWORD continue_status, int id)
c906108c
SS
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"));
7a292a7a
SS
1180 res = ContinueDebugEvent (current_event.dwProcessId,
1181 current_event.dwThreadId,
1182 continue_status);
c2d11a7d 1183 continue_status = 0;
7a292a7a 1184 if (res)
c5aa993b 1185 for (th = &thread_head; (th = th->next) != NULL;)
29fe111d 1186 if (((id == -1) || (id == (int) th->id)) && th->suspend_count)
c906108c 1187 {
fa4ba8da 1188
c906108c
SS
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 }
c906108c
SS
1206 }
1207
fa4ba8da 1208 debug_registers_changed = 0;
c906108c
SS
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 */
c2d11a7d 1228static int
0a65a603 1229get_child_debug_event (int pid, struct target_waitstatus *ourstatus)
c2d11a7d
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;
c2d11a7d 1236
7393af7c 1237 last_sig = TARGET_SIGNAL_0;
9d3789f7 1238
8a892701 1239 if (!(debug_event = WaitForDebugEvent (&current_event, 1000)))
29fe111d 1240 goto out;
c2d11a7d
JM
1241
1242 event_count++;
1243 continue_status = DBG_CONTINUE;
c2d11a7d 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)
c2d11a7d
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 }
c2d11a7d 1268 /* Record the existence of this thread */
8a892701
CF
1269 th = child_add_thread (current_event.dwThreadId,
1270 current_event.u.CreateThread.hThread);
c2d11a7d
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;
c2d11a7d
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 }
c2d11a7d
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 }
c2d11a7d 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;
c2d11a7d 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;
c2d11a7d
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;
c2d11a7d
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;
c2d11a7d
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);
c2d11a7d 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 ();
c2d11a7d
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;
c2d11a7d
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;
c2d11a7d
JM
1363 break;
1364
8a892701 1365 case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */
c2d11a7d 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;
c2d11a7d 1374 break;
9d3789f7 1375
c2d11a7d 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",
c2d11a7d
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 }
c2d11a7d
JM
1394
1395out:
450005e7 1396 return retval;
c2d11a7d
JM
1397}
1398
c2d11a7d 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)
c906108c 1402{
39f77062
KB
1403 int pid = PIDGET (ptid);
1404
c906108c
SS
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,
1407 which needs a current_thread->h. But some of these exceptions mark
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;
c906108c 1419
98bbd631
AC
1420 if (deprecated_ui_loop_hook != NULL)
1421 detach = deprecated_ui_loop_hook (0);
7a292a7a 1422
450005e7
CF
1423 if (detach)
1424 child_kill_inferior ();
1425 }
1426 }
c906108c
SS
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));
1df84f13 1444 push_target (&deprecated_child_ops);
5633f842 1445 disable_breakpoints_in_shlibs (1);
9d3789f7
CF
1446 child_clear_solibs ();
1447 clear_proceed_status ();
1448 init_wait_for_inferior ();
1449
1450 target_terminal_init ();
1451 target_terminal_inferior ();
1452
1453 while (1)
1454 {
1455 stop_after_trap = 1;
1456 wait_for_inferior ();
1457 if (stop_signal != TARGET_SIGNAL_TRAP)
1458 resume (0, stop_signal);
1459 else
1460 break;
1461 }
1462 stop_after_trap = 0;
1463 return;
1464}
1465
02cc9f49
CV
1466/* Since Windows XP, detaching from a process is supported by Windows.
1467 The following code tries loading the appropriate functions dynamically.
1468 If loading these functions succeeds use them to actually detach from
1469 the inferior process, otherwise behave as usual, pretending that
1470 detach has worked. */
1471static BOOL WINAPI (*DebugSetProcessKillOnExit)(BOOL);
1472static BOOL WINAPI (*DebugActiveProcessStop)(DWORD);
1473
1474static int
5ae5f592 1475has_detach_ability (void)
02cc9f49
CV
1476{
1477 static HMODULE kernel32 = NULL;
1478
1479 if (!kernel32)
1480 kernel32 = LoadLibrary ("kernel32.dll");
1481 if (kernel32)
1482 {
1483 if (!DebugSetProcessKillOnExit)
1484 DebugSetProcessKillOnExit = GetProcAddress (kernel32,
1485 "DebugSetProcessKillOnExit");
1486 if (!DebugActiveProcessStop)
1487 DebugActiveProcessStop = GetProcAddress (kernel32,
1488 "DebugActiveProcessStop");
1489 if (DebugSetProcessKillOnExit && DebugActiveProcessStop)
1490 return 1;
1491 }
1492 return 0;
1493}
c906108c 1494
616a9dc4
CV
1495/* Try to set or remove a user privilege to the current process. Return -1
1496 if that fails, the previous setting of that privilege otherwise.
1497
1498 This code is copied from the Cygwin source code and rearranged to allow
1499 dynamically loading of the needed symbols from advapi32 which is only
1500 available on NT/2K/XP. */
1501static int
1502set_process_privilege (const char *privilege, BOOL enable)
1503{
1504 static HMODULE advapi32 = NULL;
1505 static BOOL WINAPI (*OpenProcessToken)(HANDLE, DWORD, PHANDLE);
1506 static BOOL WINAPI (*LookupPrivilegeValue)(LPCSTR, LPCSTR, PLUID);
1507 static BOOL WINAPI (*AdjustTokenPrivileges)(HANDLE, BOOL, PTOKEN_PRIVILEGES,
1508 DWORD, PTOKEN_PRIVILEGES, PDWORD);
1509
1510 HANDLE token_hdl = NULL;
1511 LUID restore_priv;
1512 TOKEN_PRIVILEGES new_priv, orig_priv;
1513 int ret = -1;
1514 DWORD size;
1515
1516 if (GetVersion () >= 0x80000000) /* No security availbale on 9x/Me */
1517 return 0;
1518
1519 if (!advapi32)
1520 {
1521 if (!(advapi32 = LoadLibrary ("advapi32.dll")))
1522 goto out;
1523 if (!OpenProcessToken)
1524 OpenProcessToken = GetProcAddress (advapi32, "OpenProcessToken");
1525 if (!LookupPrivilegeValue)
1526 LookupPrivilegeValue = GetProcAddress (advapi32,
1527 "LookupPrivilegeValueA");
1528 if (!AdjustTokenPrivileges)
1529 AdjustTokenPrivileges = GetProcAddress (advapi32,
1530 "AdjustTokenPrivileges");
1531 if (!OpenProcessToken || !LookupPrivilegeValue || !AdjustTokenPrivileges)
295732ea 1532 {
616a9dc4
CV
1533 advapi32 = NULL;
1534 goto out;
1535 }
1536 }
295732ea 1537
616a9dc4
CV
1538 if (!OpenProcessToken (GetCurrentProcess (),
1539 TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES,
1540 &token_hdl))
1541 goto out;
1542
1543 if (!LookupPrivilegeValue (NULL, privilege, &restore_priv))
1544 goto out;
1545
1546 new_priv.PrivilegeCount = 1;
1547 new_priv.Privileges[0].Luid = restore_priv;
1548 new_priv.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
1549
1550 if (!AdjustTokenPrivileges (token_hdl, FALSE, &new_priv,
295732ea 1551 sizeof orig_priv, &orig_priv, &size))
616a9dc4
CV
1552 goto out;
1553#if 0
1554 /* Disabled, otherwise every `attach' in an unprivileged user session
1555 would raise the "Failed to get SE_DEBUG_NAME privilege" warning in
1556 child_attach(). */
1557 /* AdjustTokenPrivileges returns TRUE even if the privilege could not
1558 be enabled. GetLastError () returns an correct error code, though. */
1559 if (enable && GetLastError () == ERROR_NOT_ALL_ASSIGNED)
1560 goto out;
1561#endif
1562
1563 ret = orig_priv.Privileges[0].Attributes == SE_PRIVILEGE_ENABLED ? 1 : 0;
1564
1565out:
1566 if (token_hdl)
1567 CloseHandle (token_hdl);
1568
1569 return ret;
1570}
1571
02cc9f49 1572/* Attach to process PID, then initialize for debugging it. */
c906108c 1573static void
fba45db2 1574child_attach (char *args, int from_tty)
c906108c
SS
1575{
1576 BOOL ok;
559e75c0 1577 DWORD pid;
c906108c
SS
1578
1579 if (!args)
e2e0b3e5 1580 error_no_arg (_("process-id to attach"));
c906108c 1581
616a9dc4
CV
1582 if (set_process_privilege (SE_DEBUG_NAME, TRUE) < 0)
1583 {
1584 printf_unfiltered ("Warning: Failed to get SE_DEBUG_NAME privilege\n");
1585 printf_unfiltered ("This can cause attach to fail on Windows NT/2K/XP\n");
1586 }
1587
baa93fa6
CF
1588 pid = strtoul (args, 0, 0); /* Windows pid */
1589
d460b7f5 1590 child_init_thread_list ();
9d3789f7 1591 ok = DebugActiveProcess (pid);
91a175b3 1592 saw_create = 0;
c906108c
SS
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)
8a3fe4f8 1603 error (_("Can't attach to process."));
baa93fa6 1604 }
c906108c 1605
02cc9f49 1606 if (has_detach_ability ())
3ade5333
CF
1607 DebugSetProcessKillOnExit (FALSE);
1608
1609 attach_flag = 1;
02cc9f49 1610
c906108c
SS
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)));
c906108c
SS
1618 else
1619 printf_unfiltered ("Attaching to %s\n",
39f77062 1620 target_pid_to_str (pid_to_ptid (pid)));
c906108c
SS
1621
1622 gdb_flush (gdb_stdout);
1623 }
1624
9d3789f7
CF
1625 do_initial_child_stuff (pid);
1626 target_terminal_ours ();
c906108c
SS
1627}
1628
1629static void
0a65a603 1630child_detach (char *args, int from_tty)
c906108c 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 {
8a3fe4f8 1640 error (_("Can't detach process %lu (error %lu)"),
02cc9f49
CV
1641 current_event.dwProcessId, GetLastError ());
1642 detached = 0;
3bccec63 1643 }
02cc9f49
CV
1644 DebugSetProcessKillOnExit (FALSE);
1645 }
1646 if (detached && from_tty)
c906108c
SS
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);
c906108c
SS
1653 gdb_flush (gdb_stdout);
1654 }
39f77062 1655 inferior_ptid = null_ptid;
1df84f13 1656 unpush_target (&deprecated_child_ops);
c906108c
SS
1657}
1658
47216e51
CV
1659char *
1660child_pid_to_exec_file (int pid)
1661{
1662 /* Try to find the process path using the Cygwin internal process list
1663 pid isn't a valid pid, unfortunately. Use current_event.dwProcessId
1664 instead. */
1665 /* TODO: Also find native Windows processes using CW_GETPINFO_FULL. */
1666
1667 static char path[MAX_PATH + 1];
1668 char *path_ptr = NULL;
1669 int cpid;
1670 struct external_pinfo *pinfo;
1671
1672 cygwin_internal (CW_LOCK_PINFO, 1000);
1673 for (cpid = 0;
1674 (pinfo = (struct external_pinfo *)
1675 cygwin_internal (CW_GETPINFO, cpid | CW_NEXTPID));
1676 cpid = pinfo->pid)
1677 {
1678 if (pinfo->dwProcessId == current_event.dwProcessId) /* Got it */
1679 {
1680 cygwin_conv_to_full_posix_path (pinfo->progname, path);
1681 path_ptr = path;
1682 break;
1683 }
1684 }
1685 cygwin_internal (CW_UNLOCK_PINFO);
1686 return path_ptr;
1687}
1688
c906108c
SS
1689/* Print status information about what we're accessing. */
1690
1691static void
0a65a603 1692child_files_info (struct target_ops *ignore)
c906108c
SS
1693{
1694 printf_unfiltered ("\tUsing the running image of %s %s.\n",
39f77062 1695 attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid));
c906108c
SS
1696}
1697
c906108c 1698static void
0a65a603 1699child_open (char *arg, int from_tty)
c906108c 1700{
8a3fe4f8 1701 error (_("Use the \"run\" command to start a Unix child process."));
c906108c
SS
1702}
1703
39f77062 1704/* Start an inferior win32 child process and sets inferior_ptid to its pid.
c906108c
SS
1705 EXEC_FILE is the file to run.
1706 ALLARGS is a string containing the arguments to the program.
1707 ENV is the environment vector to pass. Errors reported with error(). */
1708
1709static void
c27cda74
AC
1710child_create_inferior (char *exec_file, char *allargs, char **env,
1711 int from_tty)
c906108c 1712{
c906108c
SS
1713 char *winenv;
1714 char *temp;
c5aa993b 1715 int envlen;
c906108c 1716 int i;
c906108c
SS
1717 STARTUPINFO si;
1718 PROCESS_INFORMATION pi;
c906108c
SS
1719 BOOL ret;
1720 DWORD flags;
1721 char *args;
dfe7f3ac
CF
1722 char real_path[MAXPATHLEN];
1723 char *toexec;
349b409f
CF
1724 char shell[MAX_PATH + 1]; /* Path to shell */
1725 const char *sh;
2becadee
CF
1726 int tty;
1727 int ostdin, ostdout, ostderr;
c906108c
SS
1728
1729 if (!exec_file)
8a3fe4f8 1730 error (_("No executable specified, use `target exec'."));
c906108c
SS
1731
1732 memset (&si, 0, sizeof (si));
1733 si.cb = sizeof (si);
1734
349b409f 1735 if (!useshell)
dfe7f3ac
CF
1736 {
1737 flags = DEBUG_ONLY_THIS_PROCESS;
1738 cygwin_conv_to_win32_path (exec_file, real_path);
1739 toexec = real_path;
1740 }
1741 else
1742 {
349b409f
CF
1743 char *newallargs;
1744 sh = getenv ("SHELL");
1745 if (!sh)
1746 sh = "/bin/sh";
1747 cygwin_conv_to_win32_path (sh, shell);
1748 newallargs = alloca (sizeof (" -c 'exec '") + strlen (exec_file)
1749 + strlen (allargs) + 2);
dfe7f3ac
CF
1750 sprintf (newallargs, " -c 'exec %s %s'", exec_file, allargs);
1751 allargs = newallargs;
1752 toexec = shell;
1753 flags = DEBUG_PROCESS;
1754 }
c906108c 1755
eeb25b8a
PM
1756 if (new_group)
1757 flags |= CREATE_NEW_PROCESS_GROUP;
1758
1759 if (new_console)
1760 flags |= CREATE_NEW_CONSOLE;
1761
3ade5333
CF
1762 attach_flag = 0;
1763
dfe7f3ac
CF
1764 args = alloca (strlen (toexec) + strlen (allargs) + 2);
1765 strcpy (args, toexec);
c906108c
SS
1766 strcat (args, " ");
1767 strcat (args, allargs);
1768
1769 /* Prepare the environment vars for CreateProcess. */
1770 {
349b409f 1771 /* This code used to assume all env vars were file names and would
c906108c
SS
1772 translate them all to win32 style. That obviously doesn't work in the
1773 general case. The current rule is that we only translate PATH.
1774 We need to handle PATH because we're about to call CreateProcess and
1775 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
1776 in both posix and win32 environments. cygwin.dll will change it back
1777 to posix style if necessary. */
1778
1779 static const char *conv_path_names[] =
c5aa993b
JM
1780 {
1781 "PATH=",
1782 0
1783 };
c906108c
SS
1784
1785 /* CreateProcess takes the environment list as a null terminated set of
1786 strings (i.e. two nulls terminate the list). */
1787
1788 /* Get total size for env strings. */
1789 for (envlen = 0, i = 0; env[i] && *env[i]; i++)
1790 {
1791 int j, len;
1792
1793 for (j = 0; conv_path_names[j]; j++)
1794 {
1795 len = strlen (conv_path_names[j]);
1796 if (strncmp (conv_path_names[j], env[i], len) == 0)
1797 {
29fe111d 1798 if (cygwin_posix_path_list_p (env[i] + len))
c906108c 1799 envlen += len
29fe111d 1800 + cygwin_posix_to_win32_path_list_buf_size (env[i] + len);
c906108c
SS
1801 else
1802 envlen += strlen (env[i]) + 1;
1803 break;
1804 }
1805 }
1806 if (conv_path_names[j] == NULL)
1807 envlen += strlen (env[i]) + 1;
1808 }
1809
1810 winenv = alloca (envlen + 1);
1811
1812 /* Copy env strings into new buffer. */
1813 for (temp = winenv, i = 0; env[i] && *env[i]; i++)
1814 {
1815 int j, len;
1816
1817 for (j = 0; conv_path_names[j]; j++)
1818 {
1819 len = strlen (conv_path_names[j]);
1820 if (strncmp (conv_path_names[j], env[i], len) == 0)
1821 {
29fe111d 1822 if (cygwin_posix_path_list_p (env[i] + len))
c906108c
SS
1823 {
1824 memcpy (temp, env[i], len);
29fe111d 1825 cygwin_posix_to_win32_path_list (env[i] + len, temp + len);
c906108c
SS
1826 }
1827 else
1828 strcpy (temp, env[i]);
1829 break;
1830 }
1831 }
1832 if (conv_path_names[j] == NULL)
1833 strcpy (temp, env[i]);
1834
1835 temp += strlen (temp) + 1;
1836 }
1837
1838 /* Final nil string to terminate new env. */
1839 *temp = 0;
1840 }
1841
2becadee
CF
1842 if (!inferior_io_terminal)
1843 tty = ostdin = ostdout = ostderr = -1;
1844 else
1845 {
1846 tty = open (inferior_io_terminal, O_RDWR | O_NOCTTY);
1847 if (tty < 0)
1848 {
1849 print_sys_errmsg (inferior_io_terminal, errno);
1850 ostdin = ostdout = ostderr = -1;
1851 }
1852 else
1853 {
1854 ostdin = dup (0);
1855 ostdout = dup (1);
1856 ostderr = dup (2);
1857 dup2 (tty, 0);
1858 dup2 (tty, 1);
1859 dup2 (tty, 2);
1860 }
1861 }
1862
d460b7f5 1863 child_init_thread_list ();
c906108c 1864 ret = CreateProcess (0,
c5aa993b 1865 args, /* command line */
c906108c
SS
1866 NULL, /* Security */
1867 NULL, /* thread */
1868 TRUE, /* inherit handles */
1869 flags, /* start flags */
1870 winenv,
1871 NULL, /* current directory */
1872 &si,
1873 &pi);
2becadee
CF
1874 if (tty >= 0)
1875 {
1876 close (tty);
1877 dup2 (ostdin, 0);
1878 dup2 (ostdout, 1);
1879 dup2 (ostderr, 2);
1880 close (ostdin);
1881 close (ostdout);
1882 close (ostderr);
1883 }
1884
c906108c 1885 if (!ret)
8a3fe4f8
AC
1886 error (_("Error creating process %s, (error %d)."),
1887 exec_file, (unsigned) GetLastError ());
c906108c 1888
700b351b
CF
1889 CloseHandle (pi.hThread);
1890 CloseHandle (pi.hProcess);
dfe7f3ac
CF
1891
1892 if (useshell && shell[0] != '\0')
1893 saw_create = -1;
1894 else
1895 saw_create = 0;
1896
9d3789f7 1897 do_initial_child_stuff (pi.dwProcessId);
ed9a39eb 1898
8e860359 1899 /* child_continue (DBG_CONTINUE, -1); */
c2d11a7d 1900 proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
c906108c
SS
1901}
1902
1903static void
fba45db2 1904child_mourn_inferior (void)
c906108c 1905{
8a892701 1906 (void) child_continue (DBG_CONTINUE, -1);
fa4ba8da 1907 i386_cleanup_dregs();
1df84f13 1908 unpush_target (&deprecated_child_ops);
c906108c
SS
1909 generic_mourn_inferior ();
1910}
1911
1912/* Send a SIGINT to the process group. This acts just like the user typed a
1913 ^C on the controlling terminal. */
1914
1915static void
fba45db2 1916child_stop (void)
c906108c
SS
1917{
1918 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
c2d11a7d 1919 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
c5aa993b 1920 registers_changed (); /* refresh register state */
c906108c
SS
1921}
1922
1923int
1924child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
0a65a603
AC
1925 int write, struct mem_attrib *mem,
1926 struct target_ops *target)
c906108c 1927{
6f17862b 1928 DWORD done = 0;
c906108c
SS
1929 if (write)
1930 {
29fe111d
CF
1931 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
1932 len, (DWORD) memaddr));
6f17862b
CF
1933 if (!WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our,
1934 len, &done))
1935 done = 0;
c906108c
SS
1936 FlushInstructionCache (current_process_handle, (LPCVOID) memaddr, len);
1937 }
1938 else
1939 {
29fe111d
CF
1940 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
1941 len, (DWORD) memaddr));
6f17862b
CF
1942 if (!ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our,
1943 len, &done))
1944 done = 0;
c906108c
SS
1945 }
1946 return done;
1947}
1948
1949void
1950child_kill_inferior (void)
1951{
1952 CHECK (TerminateProcess (current_process_handle, 0));
1953
1954 for (;;)
1955 {
8a892701 1956 if (!child_continue (DBG_CONTINUE, -1))
c906108c
SS
1957 break;
1958 if (!WaitForDebugEvent (&current_event, INFINITE))
1959 break;
1960 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
1961 break;
1962 }
1963
1964 CHECK (CloseHandle (current_process_handle));
1965
1966 /* this may fail in an attached process so don't check. */
3ade5333
CF
1967 if (current_thread && current_thread->h)
1968 (void) CloseHandle (current_thread->h);
c5aa993b 1969 target_mourn_inferior (); /* or just child_mourn_inferior? */
c906108c
SS
1970}
1971
1972void
39f77062 1973child_resume (ptid_t ptid, int step, enum target_signal sig)
c906108c 1974{
c906108c 1975 thread_info *th;
7393af7c
PM
1976 DWORD continue_status = DBG_CONTINUE;
1977
39f77062 1978 int pid = PIDGET (ptid);
8a892701 1979
7393af7c
PM
1980 if (sig != TARGET_SIGNAL_0)
1981 {
1982 if (current_event.dwDebugEventCode != EXCEPTION_DEBUG_EVENT)
1983 {
1984 DEBUG_EXCEPT(("Cannot continue with signal %d here.\n",sig));
1985 }
1986 else if (sig == last_sig)
1987 continue_status = DBG_EXCEPTION_NOT_HANDLED;
1988 else
1989#if 0
1990/* This code does not seem to work, because
1991 the kernel does probably not consider changes in the ExceptionRecord
dfe7f3ac 1992 structure when passing the exception to the inferior.
7393af7c
PM
1993 Note that this seems possible in the exception handler itself. */
1994 {
1995 int i;
1996 for (i = 0; xlate[i].them != -1; i++)
1997 if (xlate[i].us == sig)
1998 {
1999 current_event.u.Exception.ExceptionRecord.ExceptionCode =
2000 xlate[i].them;
2001 continue_status = DBG_EXCEPTION_NOT_HANDLED;
2002 break;
2003 }
2004 if (continue_status == DBG_CONTINUE)
2005 {
2006 DEBUG_EXCEPT(("Cannot continue with signal %d.\n",sig));
2007 }
2008 }
2009#endif
dfe7f3ac 2010 DEBUG_EXCEPT(("Can only continue with recieved signal %d.\n",
7393af7c
PM
2011 last_sig));
2012 }
2013
2014 last_sig = TARGET_SIGNAL_0;
c906108c
SS
2015
2016 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
2017 pid, step, sig));
2018
2019 /* Get context for currently selected thread */
2020 th = thread_rec (current_event.dwThreadId, FALSE);
450005e7 2021 if (th)
c906108c 2022 {
450005e7
CF
2023 if (step)
2024 {
2025 /* Single step by setting t bit */
2026 child_fetch_inferior_registers (PS_REGNUM);
2027 th->context.EFlags |= FLAG_TRACE_BIT;
2028 }
c906108c 2029
450005e7
CF
2030 if (th->context.ContextFlags)
2031 {
caad7706
CF
2032 if (debug_registers_changed)
2033 {
2034 th->context.Dr0 = dr[0];
2035 th->context.Dr1 = dr[1];
2036 th->context.Dr2 = dr[2];
2037 th->context.Dr3 = dr[3];
2038 /* th->context.Dr6 = dr[6];
2039 FIXME: should we set dr6 also ?? */
2040 th->context.Dr7 = dr[7];
2041 }
450005e7
CF
2042 CHECK (SetThreadContext (th->h, &th->context));
2043 th->context.ContextFlags = 0;
2044 }
c906108c
SS
2045 }
2046
2047 /* Allow continuing with the same signal that interrupted us.
2048 Otherwise complain. */
c906108c 2049
8a892701 2050 child_continue (continue_status, pid);
c906108c
SS
2051}
2052
2053static void
fba45db2 2054child_prepare_to_store (void)
c906108c
SS
2055{
2056 /* Do nothing, since we can store individual regs */
2057}
2058
2059static int
fba45db2 2060child_can_run (void)
c906108c
SS
2061{
2062 return 1;
2063}
2064
2065static void
0a65a603 2066child_close (int x)
c906108c 2067{
39f77062 2068 DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n",
3bccec63 2069 PIDGET (inferior_ptid)));
c906108c
SS
2070}
2071
c5aa993b
JM
2072static void
2073init_child_ops (void)
c906108c 2074{
1df84f13
AC
2075 deprecated_child_ops.to_shortname = "child";
2076 deprecated_child_ops.to_longname = "Win32 child process";
2077 deprecated_child_ops.to_doc = "Win32 child process (started by the \"run\" command).";
2078 deprecated_child_ops.to_open = child_open;
2079 deprecated_child_ops.to_close = child_close;
2080 deprecated_child_ops.to_attach = child_attach;
2081 deprecated_child_ops.to_detach = child_detach;
2082 deprecated_child_ops.to_resume = child_resume;
2083 deprecated_child_ops.to_wait = child_wait;
2084 deprecated_child_ops.to_fetch_registers = child_fetch_inferior_registers;
2085 deprecated_child_ops.to_store_registers = child_store_inferior_registers;
2086 deprecated_child_ops.to_prepare_to_store = child_prepare_to_store;
c8e73a31 2087 deprecated_child_ops.deprecated_xfer_memory = child_xfer_memory;
1df84f13
AC
2088 deprecated_child_ops.to_files_info = child_files_info;
2089 deprecated_child_ops.to_insert_breakpoint = memory_insert_breakpoint;
2090 deprecated_child_ops.to_remove_breakpoint = memory_remove_breakpoint;
2091 deprecated_child_ops.to_terminal_init = terminal_init_inferior;
2092 deprecated_child_ops.to_terminal_inferior = terminal_inferior;
2093 deprecated_child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
2094 deprecated_child_ops.to_terminal_ours = terminal_ours;
2095 deprecated_child_ops.to_terminal_save_ours = terminal_save_ours;
2096 deprecated_child_ops.to_terminal_info = child_terminal_info;
2097 deprecated_child_ops.to_kill = child_kill_inferior;
2098 deprecated_child_ops.to_create_inferior = child_create_inferior;
2099 deprecated_child_ops.to_mourn_inferior = child_mourn_inferior;
2100 deprecated_child_ops.to_can_run = child_can_run;
2101 deprecated_child_ops.to_thread_alive = win32_child_thread_alive;
2102 deprecated_child_ops.to_pid_to_str = cygwin_pid_to_str;
2103 deprecated_child_ops.to_stop = child_stop;
2104 deprecated_child_ops.to_stratum = process_stratum;
2105 deprecated_child_ops.to_has_all_memory = 1;
2106 deprecated_child_ops.to_has_memory = 1;
2107 deprecated_child_ops.to_has_stack = 1;
2108 deprecated_child_ops.to_has_registers = 1;
2109 deprecated_child_ops.to_has_execution = 1;
2110 deprecated_child_ops.to_magic = OPS_MAGIC;
2111 deprecated_child_ops.to_pid_to_exec_file = child_pid_to_exec_file;
c906108c
SS
2112}
2113
2114void
a6b6b089 2115_initialize_win32_nat (void)
c906108c 2116{
fa58ee11
EZ
2117 struct cmd_list_element *c;
2118
c5aa993b 2119 init_child_ops ();
c906108c 2120
fa58ee11 2121 c = add_com ("dll-symbols", class_files, dll_symbol_command,
1bedd215 2122 _("Load dll library symbols from FILE."));
5ba2abeb 2123 set_cmd_completer (c, filename_completer);
450005e7
CF
2124
2125 add_com_alias ("sharedlibrary", "dll-symbols", class_alias, 1);
2126
5bf193a2
AC
2127 add_setshow_boolean_cmd ("shell", class_support, &useshell, _("\
2128Set use of shell to start subprocess."), _("\
2129Show use of shell to start subprocess."), NULL,
2130 NULL,
2131 NULL, /* FIXME: i18n: */
2132 &setlist, &showlist);
2133
2134 add_setshow_boolean_cmd ("new-console", class_support, &new_console, _("\
2135Set creation of new console when creating child process."), _("\
2136Show creation of new console when creating child process."), NULL,
2137 NULL,
2138 NULL, /* FIXME: i18n: */
2139 &setlist, &showlist);
2140
2141 add_setshow_boolean_cmd ("new-group", class_support, &new_group, _("\
2142Set creation of new group when creating child process."), _("\
2143Show creation of new group when creating child process."), NULL,
2144 NULL,
2145 NULL, /* FIXME: i18n: */
2146 &setlist, &showlist);
2147
2148 add_setshow_boolean_cmd ("debugexec", class_support, &debug_exec, _("\
2149Set whether to display execution in child process."), _("\
2150Show whether to display execution in child process."), NULL,
2151 NULL,
2152 NULL, /* FIXME: i18n: */
2153 &setlist, &showlist);
2154
2155 add_setshow_boolean_cmd ("debugevents", class_support, &debug_events, _("\
2156Set whether to display kernel events in child process."), _("\
2157Show whether to display kernel events in child process."), NULL,
2158 NULL,
2159 NULL, /* FIXME: i18n: */
2160 &setlist, &showlist);
2161
2162 add_setshow_boolean_cmd ("debugmemory", class_support, &debug_memory, _("\
2163Set whether to display memory accesses in child process."), _("\
2164Show whether to display memory accesses in child process."), NULL,
2165 NULL,
2166 NULL, /* FIXME: i18n: */
2167 &setlist, &showlist);
2168
2169 add_setshow_boolean_cmd ("debugexceptions", class_support,
2170 &debug_exceptions, _("\
2171Set whether to display kernel exceptions in child process."), _("\
2172Show whether to display kernel exceptions in child process."), NULL,
2173 NULL,
2174 NULL, /* FIXME: i18n: */
2175 &setlist, &showlist);
c906108c 2176
1bedd215 2177 add_info ("dll", info_dll_command, _("Status of loaded DLLs."));
450005e7
CF
2178 add_info_alias ("sharedlibrary", "dll", 1);
2179
c1748f97 2180 add_prefix_cmd ("w32", class_info, info_w32_command,
1bedd215 2181 _("Print information specific to Win32 debugging."),
baa93fa6 2182 &info_w32_cmdlist, "info w32 ", 0, &infolist);
c1748f97
PM
2183
2184 add_cmd ("selector", class_info, display_selectors,
1a966eab 2185 _("Display selectors infos."),
c1748f97
PM
2186 &info_w32_cmdlist);
2187
1df84f13 2188 add_target (&deprecated_child_ops);
c906108c
SS
2189}
2190
fa4ba8da
PM
2191/* Hardware watchpoint support, adapted from go32-nat.c code. */
2192
2193/* Pass the address ADDR to the inferior in the I'th debug register.
2194 Here we just store the address in dr array, the registers will be
2195 actually set up when child_continue is called. */
2196void
2197cygwin_set_dr (int i, CORE_ADDR addr)
2198{
2199 if (i < 0 || i > 3)
2200 internal_error (__FILE__, __LINE__,
e2e0b3e5 2201 _("Invalid register %d in cygwin_set_dr.\n"), i);
fa4ba8da
PM
2202 dr[i] = (unsigned) addr;
2203 debug_registers_changed = 1;
2204 debug_registers_used = 1;
2205}
2206
2207/* Pass the value VAL to the inferior in the DR7 debug control
2208 register. Here we just store the address in D_REGS, the watchpoint
2209 will be actually set up in child_wait. */
2210void
2211cygwin_set_dr7 (unsigned val)
2212{
2213 dr[7] = val;
2214 debug_registers_changed = 1;
2215 debug_registers_used = 1;
2216}
2217
2218/* Get the value of the DR6 debug status register from the inferior.
2219 Here we just return the value stored in dr[6]
2220 by the last call to thread_rec for current_event.dwThreadId id. */
2221unsigned
2222cygwin_get_dr6 (void)
2223{
2224 return dr[6];
2225}
2226
c906108c
SS
2227/* Determine if the thread referenced by "pid" is alive
2228 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
2229 it means that the pid has died. Otherwise it is assumed to be alive. */
2230static int
39f77062 2231win32_child_thread_alive (ptid_t ptid)
c906108c 2232{
39f77062
KB
2233 int pid = PIDGET (ptid);
2234
c5aa993b
JM
2235 return WaitForSingleObject (thread_rec (pid, FALSE)->h, 0) == WAIT_OBJECT_0 ?
2236 FALSE : TRUE;
c906108c
SS
2237}
2238
2239/* Convert pid to printable format. */
2240char *
39f77062 2241cygwin_pid_to_str (ptid_t ptid)
c906108c
SS
2242{
2243 static char buf[80];
39f77062
KB
2244 int pid = PIDGET (ptid);
2245
29fe111d 2246 if ((DWORD) pid == current_event.dwProcessId)
b69571f5 2247 sprintf (buf, "process %d", pid);
c906108c 2248 else
b69571f5 2249 sprintf (buf, "thread %ld.0x%x", current_event.dwProcessId, pid);
c906108c
SS
2250 return buf;
2251}
8e860359
CF
2252
2253static int
2254core_dll_symbols_add (char *dll_name, DWORD base_addr)
2255{
2256 struct objfile *objfile;
2257 char *objfile_basename;
2258 const char *dll_basename;
2259
2260 if (!(dll_basename = strrchr (dll_name, '/')))
2261 dll_basename = dll_name;
2262 else
2263 dll_basename++;
2264
2265 ALL_OBJFILES (objfile)
2266 {
2267 objfile_basename = strrchr (objfile->name, '/');
2268
2269 if (objfile_basename &&
2270 strcmp (dll_basename, objfile_basename + 1) == 0)
2271 {
2272 printf_unfiltered ("%08lx:%s (symbols previously loaded)\n",
2273 base_addr, dll_name);
2274 goto out;
2275 }
2276 }
2277
6780dcde
MS
2278 register_loaded_dll (dll_name, base_addr + 0x1000);
2279 solib_symbols_add (dll_name, 0, (CORE_ADDR) base_addr + 0x1000);
8e860359 2280
6780dcde
MS
2281 out:
2282 return 1;
2283}
8e860359 2284
6780dcde
MS
2285typedef struct
2286{
2287 struct target_ops *target;
2288 bfd_vma addr;
2289} map_code_section_args;
8e860359 2290
6780dcde
MS
2291static void
2292map_single_dll_code_section (bfd * abfd, asection * sect, void *obj)
2293{
2294 int old;
2295 int update_coreops;
2296 struct section_table *new_target_sect_ptr;
8e860359 2297
6780dcde
MS
2298 map_code_section_args *args = (map_code_section_args *) obj;
2299 struct target_ops *target = args->target;
2300 if (sect->flags & SEC_CODE)
2301 {
2302 update_coreops = core_ops.to_sections == target->to_sections;
8e860359 2303
6780dcde
MS
2304 if (target->to_sections)
2305 {
2306 old = target->to_sections_end - target->to_sections;
2307 target->to_sections = (struct section_table *)
2308 xrealloc ((char *) target->to_sections,
2309 (sizeof (struct section_table)) * (1 + old));
2310 }
2311 else
2312 {
2313 old = 0;
2314 target->to_sections = (struct section_table *)
2315 xmalloc ((sizeof (struct section_table)));
2316 }
2317 target->to_sections_end = target->to_sections + (1 + old);
8e860359 2318
6780dcde
MS
2319 /* Update the to_sections field in the core_ops structure
2320 if needed. */
2321 if (update_coreops)
2322 {
2323 core_ops.to_sections = target->to_sections;
2324 core_ops.to_sections_end = target->to_sections_end;
2325 }
2326 new_target_sect_ptr = target->to_sections + old;
2327 new_target_sect_ptr->addr = args->addr + bfd_section_vma (abfd, sect);
2328 new_target_sect_ptr->endaddr = args->addr + bfd_section_vma (abfd, sect) +
2329 bfd_section_size (abfd, sect);;
2330 new_target_sect_ptr->the_bfd_section = sect;
2331 new_target_sect_ptr->bfd = abfd;
2332 }
2333}
8e860359 2334
6780dcde
MS
2335static int
2336dll_code_sections_add (const char *dll_name, int base_addr, struct target_ops *target)
8e860359
CF
2337{
2338 bfd *dll_bfd;
2339 map_code_section_args map_args;
2340 asection *lowest_sect;
2341 char *name;
2342 if (dll_name == NULL || target == NULL)
2343 return 0;
66ed1d85 2344 name = xstrdup (dll_name);
8e860359
CF
2345 dll_bfd = bfd_openr (name, "pei-i386");
2346 if (dll_bfd == NULL)
2347 return 0;
2348
2349 if (bfd_check_format (dll_bfd, bfd_object))
2350 {
2351 lowest_sect = bfd_get_section_by_name (dll_bfd, ".text");
2352 if (lowest_sect == NULL)
2353 return 0;
2354 map_args.target = target;
2355 map_args.addr = base_addr - bfd_section_vma (dll_bfd, lowest_sect);
2356
554cb486 2357 bfd_map_over_sections (dll_bfd, &map_single_dll_code_section, (void *) (&map_args));
8e860359
CF
2358 }
2359
2360 return 1;
2361}
2362
2363static void
554cb486 2364core_section_load_dll_symbols (bfd * abfd, asection * sect, void *obj)
8e860359
CF
2365{
2366 struct target_ops *target = (struct target_ops *) obj;
2367
2368 DWORD base_addr;
2369
2370 int dll_name_size;
2371 char *dll_name = NULL;
2372 char *buf = NULL;
2373 struct win32_pstatus *pstatus;
2374 char *p;
2375
2376 if (strncmp (sect->name, ".module", 7))
2377 return;
2378
2c500098 2379 buf = (char *) xmalloc (bfd_get_section_size (sect) + 1);
8e860359
CF
2380 if (!buf)
2381 {
2382 printf_unfiltered ("memory allocation failed for %s\n", sect->name);
2383 goto out;
2384 }
2c500098 2385 if (!bfd_get_section_contents (abfd, sect, buf, 0, bfd_get_section_size (sect)))
8e860359
CF
2386 goto out;
2387
2388 pstatus = (struct win32_pstatus *) buf;
2389
2390 memmove (&base_addr, &(pstatus->data.module_info.base_address), sizeof (base_addr));
2391 dll_name_size = pstatus->data.module_info.module_name_size;
2c500098 2392 if (offsetof (struct win32_pstatus, data.module_info.module_name) + dll_name_size > bfd_get_section_size (sect))
8e860359
CF
2393 goto out;
2394
2395 dll_name = (char *) xmalloc (dll_name_size + 1);
2396 if (!dll_name)
2397 {
2398 printf_unfiltered ("memory allocation failed for %s\n", sect->name);
2399 goto out;
2400 }
2401 strncpy (dll_name, pstatus->data.module_info.module_name, dll_name_size);
2402
2403 while ((p = strchr (dll_name, '\\')))
2404 *p = '/';
2405
2406 if (!core_dll_symbols_add (dll_name, (DWORD) base_addr))
2407 printf_unfiltered ("%s: Failed to load dll symbols.\n", dll_name);
2408
2409 if (!dll_code_sections_add (dll_name, (DWORD) base_addr + 0x1000, target))
2410 printf_unfiltered ("%s: Failed to map dll code sections.\n", dll_name);
2411
2412out:
2413 if (buf)
b8c9b27d 2414 xfree (buf);
8e860359 2415 if (dll_name)
b8c9b27d 2416 xfree (dll_name);
8e860359
CF
2417 return;
2418}
2419
2420void
0a65a603
AC
2421child_solib_add (char *filename, int from_tty, struct target_ops *target,
2422 int readsyms)
8e860359 2423{
990f9fe3
FF
2424 if (!readsyms)
2425 return;
8e860359
CF
2426 if (core_bfd)
2427 {
2428 child_clear_solibs ();
2429 bfd_map_over_sections (core_bfd, &core_section_load_dll_symbols, target);
2430 }
2431 else
2432 {
2433 if (solib_end && solib_end->name)
d3ff4a77 2434 solib_end->objfile = solib_symbols_add (solib_end->name, from_tty,
3bccec63 2435 solib_end->load_addr);
8e860359
CF
2436 }
2437}
2438
2439static void
2440fetch_elf_core_registers (char *core_reg_sect,
2441 unsigned core_reg_size,
2442 int which,
2443 CORE_ADDR reg_addr)
2444{
2445 int r;
2446 if (core_reg_size < sizeof (CONTEXT))
2447 {
8a3fe4f8 2448 error (_("Core file register section too small (%u bytes)."), core_reg_size);
8e860359
CF
2449 return;
2450 }
2451 for (r = 0; r < NUM_REGS; r++)
23a6d369 2452 regcache_raw_supply (current_regcache, r, core_reg_sect + mappings[r]);
8e860359
CF
2453}
2454
2455static struct core_fns win32_elf_core_fns =
2456{
2457 bfd_target_elf_flavour,
2458 default_check_format,
2459 default_core_sniffer,
2460 fetch_elf_core_registers,
2461 NULL
2462};
2463
2464void
0613c401 2465_initialize_core_win32 (void)
8e860359 2466{
00e32a35 2467 deprecated_add_core_fns (&win32_elf_core_fns);
8e860359 2468}
2a3d5645
CF
2469
2470void
2471_initialize_check_for_gdb_ini (void)
2472{
2473 char *homedir;
2474 if (inhibit_gdbinit)
2475 return;
2476
2477 homedir = getenv ("HOME");
2478 if (homedir)
2479 {
2480 char *p;
2481 char *oldini = (char *) alloca (strlen (homedir) +
2482 sizeof ("/gdb.ini"));
2483 strcpy (oldini, homedir);
2484 p = strchr (oldini, '\0');
2485 if (p > oldini && p[-1] != '/')
2486 *p++ = '/';
2487 strcpy (p, "gdb.ini");
2488 if (access (oldini, 0) == 0)
2489 {
2490 int len = strlen (oldini);
2491 char *newini = alloca (len + 1);
dfe7f3ac 2492 sprintf (newini, "%.*s.gdbinit",
58fa08f0 2493 (int) (len - (sizeof ("gdb.ini") - 1)), oldini);
8a3fe4f8 2494 warning (_("obsolete '%s' found. Rename to '%s'."), oldini, newini);
2a3d5645
CF
2495 }
2496 }
2497}