Define SVR4 link map offset fetcher for Linux/ARM.
[deliverable/binutils-gdb.git] / gdb / windows-nat.c
CommitLineData
24e60978 1/* Target-vector operations for controlling win32 child processes, for GDB.
b6ba6518
KB
2 Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
e6433c28 4 Contributed by Cygnus Solutions, A Red Hat Company.
e88c49c3 5
24e60978
SC
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without eve nthe implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
3a4b77d8 20 Foundation, Inc., 59 Temple Place - Suite 330,
4e052eda 21 Boston, MA 02111-1307, USA. */
24e60978
SC
22
23/* by Steve Chamberlain, sac@cygnus.com */
24
3cee93ac 25/* We assume we're being built with and will be used for cygwin. */
e88c49c3 26
24e60978 27#include "defs.h"
97da3b20 28#include "tm.h" /* required for SSE registers */
24e60978
SC
29#include "frame.h" /* required by inferior.h */
30#include "inferior.h"
31#include "target.h"
24e60978
SC
32#include "gdbcore.h"
33#include "command.h"
fa58ee11 34#include "completer.h"
4e052eda 35#include "regcache.h"
2a3d5645 36#include "top.h"
24e60978
SC
37#include <signal.h>
38#include <sys/types.h>
39#include <fcntl.h>
cad9cd60 40#include <stdlib.h>
cad9cd60 41#include <windows.h>
1e37c281 42#include <imagehlp.h>
29fe111d 43#include <sys/cygwin.h>
cad9cd60 44
24e60978 45#include "buildsym.h"
1ef980b9
SC
46#include "symfile.h"
47#include "objfiles.h"
24e60978 48#include "gdb_string.h"
fdfa3315 49#include "gdbthread.h"
24e60978 50#include "gdbcmd.h"
1750a5ef 51#include <sys/param.h>
1e37c281 52#include <unistd.h>
24e60978 53
0714f9bf 54/* The ui's event loop. */
507f3c78 55extern int (*ui_loop_hook) (int signo);
0714f9bf
SS
56
57/* If we're not using the old Cygwin header file set, define the
58 following which never should have been in the generic Win32 API
59 headers in the first place since they were our own invention... */
60#ifndef _GNU_H_WINDOWS_H
9d3789f7 61enum
8e860359
CF
62 {
63 FLAG_TRACE_BIT = 0x100,
64 CONTEXT_DEBUGGER = (CONTEXT_FULL | CONTEXT_FLOATING_POINT)
65 };
0714f9bf 66#endif
8e860359
CF
67#include <sys/procfs.h>
68#include <psapi.h>
0714f9bf 69
97da3b20 70#ifdef HAVE_SSE_REGS
3bccec63 71#define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER | CONTEXT_EXTENDED_REGISTERS
97da3b20
CF
72#else
73#define CONTEXT_DEBUGGER_DR CONTEXT_DEBUGGER
74#endif
75
76
3cee93ac
CF
77/* The string sent by cygwin when it processes a signal.
78 FIXME: This should be in a cygwin include file. */
79#define CYGWIN_SIGNAL_STRING "cygwin: signal"
80
29fe111d 81#define CHECK(x) check (x, __FILE__,__LINE__)
1ef980b9
SC
82#define DEBUG_EXEC(x) if (debug_exec) printf x
83#define DEBUG_EVENTS(x) if (debug_events) printf x
84#define DEBUG_MEM(x) if (debug_memory) printf x
85#define DEBUG_EXCEPT(x) if (debug_exceptions) printf x
24e60978
SC
86
87/* Forward declaration */
88extern struct target_ops child_ops;
89
a14ed312 90static void child_stop (void);
39f77062 91static int win32_child_thread_alive (ptid_t);
a14ed312 92void child_kill_inferior (void);
3cee93ac 93
8a892701
CF
94static int last_sig = 0; /* Set if a signal was received from the
95 debugged process */
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;
105 CONTEXT context;
1e37c281 106 STACKFRAME sf;
8e860359
CF
107 }
108thread_info;
1e37c281 109
29fe111d 110static thread_info thread_head;
24e60978 111
24e60978
SC
112/* The process and thread handles for the above context. */
113
3cee93ac
CF
114static DEBUG_EVENT current_event; /* The current debug event from
115 WaitForDebugEvent */
116static HANDLE current_process_handle; /* Currently executing process */
117static thread_info *current_thread; /* Info on currently selected thread */
3a4b77d8 118static DWORD main_thread_id; /* Thread ID of the main thread */
24e60978
SC
119
120/* Counts of things. */
121static int exception_count = 0;
122static int event_count = 0;
123
124/* User options. */
125static int new_console = 0;
1e37c281 126static int new_group = 1;
3a4b77d8
JM
127static int debug_exec = 0; /* show execution */
128static int debug_events = 0; /* show events from kernel */
129static int debug_memory = 0; /* show target memory accesses */
1ef980b9 130static int debug_exceptions = 0; /* show target exceptions */
24e60978
SC
131
132/* This vector maps GDB's idea of a register's number into an address
3cee93ac 133 in the win32 exception context vector.
24e60978 134
3cee93ac 135 It also contains the bit mask needed to load the register in question.
24e60978
SC
136
137 One day we could read a reg, we could inspect the context we
138 already have loaded, if it doesn't have the bit set that we need,
139 we read that set of registers in using GetThreadContext. If the
140 context already contains what we need, we just unpack it. Then to
141 write a register, first we have to ensure that the context contains
142 the other regs of the group, and then we copy the info in and set
143 out bit. */
144
3cee93ac
CF
145#define context_offset(x) ((int)&(((CONTEXT *)NULL)->x))
146static const int mappings[] =
24e60978 147{
3a4b77d8
JM
148 context_offset (Eax),
149 context_offset (Ecx),
150 context_offset (Edx),
151 context_offset (Ebx),
152 context_offset (Esp),
153 context_offset (Ebp),
154 context_offset (Esi),
155 context_offset (Edi),
156 context_offset (Eip),
157 context_offset (EFlags),
158 context_offset (SegCs),
159 context_offset (SegSs),
160 context_offset (SegDs),
161 context_offset (SegEs),
162 context_offset (SegFs),
163 context_offset (SegGs),
164 context_offset (FloatSave.RegisterArea[0 * 10]),
165 context_offset (FloatSave.RegisterArea[1 * 10]),
166 context_offset (FloatSave.RegisterArea[2 * 10]),
167 context_offset (FloatSave.RegisterArea[3 * 10]),
168 context_offset (FloatSave.RegisterArea[4 * 10]),
169 context_offset (FloatSave.RegisterArea[5 * 10]),
170 context_offset (FloatSave.RegisterArea[6 * 10]),
171 context_offset (FloatSave.RegisterArea[7 * 10]),
1e37c281
JM
172 context_offset (FloatSave.ControlWord),
173 context_offset (FloatSave.StatusWord),
174 context_offset (FloatSave.TagWord),
175 context_offset (FloatSave.ErrorSelector),
176 context_offset (FloatSave.ErrorOffset),
177 context_offset (FloatSave.DataSelector),
178 context_offset (FloatSave.DataOffset),
d3a09475 179 context_offset (FloatSave.ErrorSelector)
97da3b20
CF
180#ifdef HAVE_SSE_REGS
181 /* XMM0-7 */ ,
182 context_offset (ExtendedRegisters[0*16]),
183 context_offset (ExtendedRegisters[1*16]),
184 context_offset (ExtendedRegisters[2*16]),
185 context_offset (ExtendedRegisters[3*16]),
186 context_offset (ExtendedRegisters[4*16]),
187 context_offset (ExtendedRegisters[5*16]),
188 context_offset (ExtendedRegisters[6*16]),
189 context_offset (ExtendedRegisters[7*16]),
190 /* MXCSR untested */
191 context_offset (ExtendedRegisters[8*16])
192#endif
24e60978
SC
193};
194
d3a09475
JM
195#undef context_offset
196
24e60978
SC
197/* This vector maps the target's idea of an exception (extracted
198 from the DEBUG_EVENT structure) to GDB's idea. */
199
200struct xlate_exception
201 {
202 int them;
203 enum target_signal us;
204 };
205
24e60978
SC
206static const struct xlate_exception
207 xlate[] =
208{
209 {EXCEPTION_ACCESS_VIOLATION, TARGET_SIGNAL_SEGV},
9cbf6c0e 210 {STATUS_STACK_OVERFLOW, TARGET_SIGNAL_SEGV},
24e60978
SC
211 {EXCEPTION_BREAKPOINT, TARGET_SIGNAL_TRAP},
212 {DBG_CONTROL_C, TARGET_SIGNAL_INT},
213 {EXCEPTION_SINGLE_STEP, TARGET_SIGNAL_TRAP},
214 {-1, -1}};
215
3cee93ac
CF
216/* Find a thread record given a thread id.
217 If get_context then also retrieve the context for this
218 thread. */
219static thread_info *
220thread_rec (DWORD id, int get_context)
24e60978 221{
3cee93ac
CF
222 thread_info *th;
223
3a4b77d8 224 for (th = &thread_head; (th = th->next) != NULL;)
3cee93ac
CF
225 if (th->id == id)
226 {
227 if (!th->suspend_count && get_context)
228 {
8a892701 229 if (get_context > 0 && id != current_event.dwThreadId)
3cee93ac
CF
230 th->suspend_count = SuspendThread (th->h) + 1;
231 else if (get_context < 0)
232 th->suspend_count = -1;
233
97da3b20 234 th->context.ContextFlags = CONTEXT_DEBUGGER_DR;
3cee93ac
CF
235 GetThreadContext (th->h, &th->context);
236 }
237 return th;
238 }
239
240 return NULL;
241}
242
243/* Add a thread to the thread list */
244static thread_info *
3a4b77d8 245child_add_thread (DWORD id, HANDLE h)
3cee93ac
CF
246{
247 thread_info *th;
248
249 if ((th = thread_rec (id, FALSE)))
250 return th;
251
252 th = (thread_info *) xmalloc (sizeof (*th));
3a4b77d8 253 memset (th, 0, sizeof (*th));
3cee93ac
CF
254 th->id = id;
255 th->h = h;
256 th->next = thread_head.next;
257 thread_head.next = th;
39f77062 258 add_thread (pid_to_ptid (id));
3cee93ac 259 return th;
24e60978
SC
260}
261
3cee93ac
CF
262/* Clear out any old thread list and reintialize it to a
263 pristine state. */
24e60978 264static void
fba45db2 265child_init_thread_list (void)
24e60978 266{
3cee93ac
CF
267 thread_info *th = &thread_head;
268
269 DEBUG_EVENTS (("gdb: child_init_thread_list\n"));
270 init_thread_list ();
271 while (th->next != NULL)
24e60978 272 {
3cee93ac
CF
273 thread_info *here = th->next;
274 th->next = here->next;
275 (void) CloseHandle (here->h);
b8c9b27d 276 xfree (here);
24e60978 277 }
3cee93ac
CF
278}
279
280/* Delete a thread from the list of threads */
281static void
282child_delete_thread (DWORD id)
283{
284 thread_info *th;
285
286 if (info_verbose)
39f77062
KB
287 printf_unfiltered ("[Deleting %s]\n", target_pid_to_str (pid_to_ptid (id)));
288 delete_thread (pid_to_ptid (id));
3cee93ac
CF
289
290 for (th = &thread_head;
291 th->next != NULL && th->next->id != id;
292 th = th->next)
293 continue;
294
295 if (th->next != NULL)
24e60978 296 {
3cee93ac
CF
297 thread_info *here = th->next;
298 th->next = here->next;
299 CloseHandle (here->h);
b8c9b27d 300 xfree (here);
24e60978
SC
301 }
302}
303
304static void
3cee93ac
CF
305check (BOOL ok, const char *file, int line)
306{
307 if (!ok)
29fe111d 308 printf_filtered ("error return %s:%d was %lu\n", file, line, GetLastError ());
3cee93ac
CF
309}
310
311static void
312do_child_fetch_inferior_registers (int r)
24e60978 313{
1e37c281
JM
314 char *context_offset = ((char *) &current_thread->context) + mappings[r];
315 long l;
316 if (r == FCS_REGNUM)
317 {
8e860359 318 l = *((long *) context_offset) & 0xffff;
1e37c281
JM
319 supply_register (r, (char *) &l);
320 }
321 else if (r == FOP_REGNUM)
322 {
8e860359 323 l = (*((long *) context_offset) >> 16) & ((1 << 11) - 1);
1e37c281
JM
324 supply_register (r, (char *) &l);
325 }
326 else if (r >= 0)
d3a09475 327 supply_register (r, context_offset);
3cee93ac 328 else
24e60978
SC
329 {
330 for (r = 0; r < NUM_REGS; r++)
3cee93ac 331 do_child_fetch_inferior_registers (r);
24e60978 332 }
3cee93ac
CF
333}
334
335static void
336child_fetch_inferior_registers (int r)
337{
39f77062 338 current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
3cee93ac
CF
339 do_child_fetch_inferior_registers (r);
340}
341
342static void
343do_child_store_inferior_registers (int r)
344{
345 if (r >= 0)
346 read_register_gen (r, ((char *) &current_thread->context) + mappings[r]);
24e60978
SC
347 else
348 {
3cee93ac
CF
349 for (r = 0; r < NUM_REGS; r++)
350 do_child_store_inferior_registers (r);
24e60978
SC
351 }
352}
353
3cee93ac
CF
354/* Store a new register value into the current thread context */
355static void
356child_store_inferior_registers (int r)
357{
39f77062 358 current_thread = thread_rec (PIDGET (inferior_ptid), TRUE);
3cee93ac
CF
359 do_child_store_inferior_registers (r);
360}
24e60978 361
1e37c281
JM
362static int psapi_loaded = 0;
363static HMODULE psapi_module_handle = NULL;
8e860359
CF
364static BOOL WINAPI (*psapi_EnumProcessModules) (HANDLE, HMODULE *, DWORD, LPDWORD) = NULL;
365static BOOL WINAPI (*psapi_GetModuleInformation) (HANDLE, HMODULE, LPMODULEINFO, DWORD) = NULL;
366static DWORD WINAPI (*psapi_GetModuleFileNameExA) (HANDLE, HMODULE, LPSTR, DWORD) = NULL;
1e37c281 367
3bccec63 368int
8e860359 369psapi_get_dll_name (DWORD BaseAddress, char *dll_name_ret)
1e37c281
JM
370{
371 DWORD len;
372 MODULEINFO mi;
373 int i;
8e860359
CF
374 HMODULE dh_buf[1];
375 HMODULE *DllHandle = dh_buf;
1e37c281
JM
376 DWORD cbNeeded;
377 BOOL ok;
378
379 if (!psapi_loaded ||
8e860359
CF
380 psapi_EnumProcessModules == NULL ||
381 psapi_GetModuleInformation == NULL ||
382 psapi_GetModuleFileNameExA == NULL)
1e37c281 383 {
8e860359
CF
384 if (psapi_loaded)
385 goto failed;
1e37c281
JM
386 psapi_loaded = 1;
387 psapi_module_handle = LoadLibrary ("psapi.dll");
388 if (!psapi_module_handle)
8e860359
CF
389 {
390 /* printf_unfiltered ("error loading psapi.dll: %u", GetLastError ()); */
391 goto failed;
392 }
393 psapi_EnumProcessModules = GetProcAddress (psapi_module_handle, "EnumProcessModules");
1e37c281
JM
394 psapi_GetModuleInformation = GetProcAddress (psapi_module_handle, "GetModuleInformation");
395 psapi_GetModuleFileNameExA = (void *) GetProcAddress (psapi_module_handle,
8e860359
CF
396 "GetModuleFileNameExA");
397 if (psapi_EnumProcessModules == NULL ||
398 psapi_GetModuleInformation == NULL ||
399 psapi_GetModuleFileNameExA == NULL)
1e37c281
JM
400 goto failed;
401 }
402
403 cbNeeded = 0;
404 ok = (*psapi_EnumProcessModules) (current_process_handle,
8e860359
CF
405 DllHandle,
406 sizeof (HMODULE),
407 &cbNeeded);
1e37c281
JM
408
409 if (!ok || !cbNeeded)
410 goto failed;
411
8e860359 412 DllHandle = (HMODULE *) alloca (cbNeeded);
1e37c281
JM
413 if (!DllHandle)
414 goto failed;
415
416 ok = (*psapi_EnumProcessModules) (current_process_handle,
8e860359
CF
417 DllHandle,
418 cbNeeded,
419 &cbNeeded);
1e37c281
JM
420 if (!ok)
421 goto failed;
422
29fe111d 423 for (i = 0; i < (int) (cbNeeded / sizeof (HMODULE)); i++)
1e37c281
JM
424 {
425 if (!(*psapi_GetModuleInformation) (current_process_handle,
8e860359
CF
426 DllHandle[i],
427 &mi,
428 sizeof (mi)))
1e37c281
JM
429 error ("Can't get module info");
430
431 len = (*psapi_GetModuleFileNameExA) (current_process_handle,
8e860359
CF
432 DllHandle[i],
433 dll_name_ret,
434 MAX_PATH);
1e37c281 435 if (len == 0)
29fe111d 436 error ("Error getting dll name: %u\n", GetLastError ());
1e37c281
JM
437
438 if ((DWORD) (mi.lpBaseOfDll) == BaseAddress)
439 return 1;
440 }
441
442failed:
443 dll_name_ret[0] = '\0';
444 return 0;
445}
446
450005e7
CF
447/* Encapsulate the information required in a call to
448 symbol_file_add_args */
8a892701
CF
449struct safe_symbol_file_add_args
450{
451 char *name;
452 int from_tty;
453 struct section_addr_info *addrs;
454 int mainline;
455 int flags;
7c5c87c0 456 struct ui_file *err, *out;
8a892701
CF
457 struct objfile *ret;
458};
459
02e423b9
CF
460/* Maintain a linked list of "so" information. */
461struct so_stuff
462{
d3ff4a77 463 struct so_stuff *next;
02e423b9 464 DWORD load_addr;
7470a420 465 int loaded;
d3ff4a77 466 struct objfile *objfile;
7470a420
CF
467 char name[1];
468} solib_start, *solib_end;
02e423b9 469
450005e7
CF
470/* Call symbol_file_add with stderr redirected. We don't care if there
471 are errors. */
8a892701
CF
472static int
473safe_symbol_file_add_stub (void *argv)
474{
475#define p ((struct safe_symbol_file_add_args *)argv)
fefd0a37 476 struct so_stuff *so = &solib_start;
02e423b9
CF
477
478 while ((so = so->next))
7470a420 479 if (so->loaded && strcasecmp (so->name, p->name) == 0)
02e423b9 480 return 0;
8a892701
CF
481 p->ret = symbol_file_add (p->name, p->from_tty, p->addrs, p->mainline, p->flags);
482 return !!p->ret;
483#undef p
484}
485
450005e7 486/* Restore gdb's stderr after calling symbol_file_add */
8a892701 487static void
7c5c87c0 488safe_symbol_file_add_cleanup (void *p)
8a892701 489{
8e860359 490#define sp ((struct safe_symbol_file_add_args *)p)
450005e7 491 gdb_flush (gdb_stderr);
7c5c87c0 492 gdb_flush (gdb_stdout);
d3ff4a77 493 ui_file_delete (gdb_stderr);
7c5c87c0 494 ui_file_delete (gdb_stdout);
d3ff4a77 495 gdb_stderr = sp->err;
9d3789f7 496 gdb_stdout = sp->out;
8e860359 497#undef sp
8a892701
CF
498}
499
450005e7 500/* symbol_file_add wrapper that prevents errors from being displayed. */
8a892701
CF
501static struct objfile *
502safe_symbol_file_add (char *name, int from_tty,
503 struct section_addr_info *addrs,
504 int mainline, int flags)
8a892701
CF
505{
506 struct safe_symbol_file_add_args p;
507 struct cleanup *cleanup;
508
7c5c87c0 509 cleanup = make_cleanup (safe_symbol_file_add_cleanup, &p);
8a892701 510
7c5c87c0
CF
511 p.err = gdb_stderr;
512 p.out = gdb_stdout;
450005e7 513 gdb_flush (gdb_stderr);
7c5c87c0 514 gdb_flush (gdb_stdout);
d3ff4a77 515 gdb_stderr = ui_file_new ();
7c5c87c0 516 gdb_stdout = ui_file_new ();
8a892701
CF
517 p.name = name;
518 p.from_tty = from_tty;
519 p.addrs = addrs;
520 p.mainline = mainline;
521 p.flags = flags;
522 catch_errors (safe_symbol_file_add_stub, &p, "", RETURN_MASK_ERROR);
523
524 do_cleanups (cleanup);
525 return p.ret;
526}
527
450005e7
CF
528/* Remember the maximum DLL length for printing in info dll command. */
529int max_dll_name_len;
530
8e860359
CF
531static void
532register_loaded_dll (const char *name, DWORD load_addr)
533{
534 struct so_stuff *so;
7470a420 535 char ppath[MAX_PATH + 1];
3f8ad85b
CF
536 char buf[MAX_PATH + 1];
537 char cwd[MAX_PATH + 1];
538 char *p;
539 WIN32_FIND_DATA w32_fd;
540 HANDLE h = FindFirstFile(name, &w32_fd);
541 size_t len;
542
543 FindClose (h);
544 strcpy (buf, name);
545 if (GetCurrentDirectory (MAX_PATH + 1, cwd))
546 {
547 p = strrchr (buf, '\\');
548 if (p)
549 p[1] = '\0';
550 SetCurrentDirectory (buf);
551 GetFullPathName (w32_fd.cFileName, MAX_PATH, buf, &p);
552 SetCurrentDirectory (cwd);
553 }
554
555 cygwin_conv_to_posix_path (buf, ppath);
7470a420
CF
556 so = (struct so_stuff *) xmalloc (sizeof (struct so_stuff) + strlen (ppath) + 8 + 1);
557 so->loaded = 0;
8e860359 558 so->load_addr = load_addr;
d3ff4a77
CF
559 so->next = NULL;
560 so->objfile = NULL;
7470a420 561 strcpy (so->name, ppath);
8e860359
CF
562
563 solib_end->next = so;
564 solib_end = so;
3f8ad85b
CF
565 len = strlen (ppath);
566 if (len > max_dll_name_len)
567 max_dll_name_len = len;
8e860359
CF
568}
569
24e60978
SC
570/* Wait for child to do something. Return pid of child, or -1 in case
571 of error; store status through argument pointer OURSTATUS. */
1750a5ef 572static int
554cb486 573handle_load_dll (void *dummy ATTRIBUTE_UNUSED)
24e60978 574{
3a4b77d8 575 LOAD_DLL_DEBUG_INFO *event = &current_event.u.LoadDll;
24e60978
SC
576 DWORD dll_name_ptr;
577 DWORD done;
3cee93ac 578 char dll_buf[MAX_PATH + 1];
450005e7 579 char *dll_name = NULL;
450005e7 580 char *p;
3cee93ac 581
3a4b77d8 582 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
3cee93ac 583
1e37c281 584 if (!psapi_get_dll_name ((DWORD) (event->lpBaseOfDll), dll_buf))
8e860359 585 dll_buf[0] = dll_buf[sizeof (dll_buf) - 1] = '\0';
3cee93ac 586
1e37c281 587 dll_name = dll_buf;
24e60978 588
3cee93ac
CF
589 /* Attempt to read the name of the dll that was detected.
590 This is documented to work only when actively debugging
591 a program. It will not work for attached processes. */
592 if (dll_name == NULL || *dll_name == '\0')
24e60978 593 {
29fe111d 594 DWORD size = event->fUnicode ? sizeof (WCHAR) : sizeof (char);
24e60978
SC
595 int len = 0;
596 char b[2];
3cee93ac
CF
597
598 ReadProcessMemory (current_process_handle,
599 (LPCVOID) event->lpImageName,
600 (char *) &dll_name_ptr,
601 sizeof (dll_name_ptr), &done);
602
603 /* See if we could read the address of a string, and that the
3bccec63 604 address isn't null. */
3cee93ac
CF
605
606 if (done != sizeof (dll_name_ptr) || !dll_name_ptr)
607 return 1;
608
24e60978
SC
609 do
610 {
3cee93ac
CF
611 ReadProcessMemory (current_process_handle,
612 (LPCVOID) (dll_name_ptr + len * size),
24e60978
SC
613 &b,
614 size,
615 &done);
616 len++;
617 }
618 while ((b[0] != 0 || b[size - 1] != 0) && done == size);
619
24e60978
SC
620 dll_name = alloca (len);
621
3cee93ac 622 if (event->fUnicode)
24e60978
SC
623 {
624 WCHAR *unicode_dll_name = (WCHAR *) alloca (len * sizeof (WCHAR));
3cee93ac
CF
625 ReadProcessMemory (current_process_handle,
626 (LPCVOID) dll_name_ptr,
24e60978
SC
627 unicode_dll_name,
628 len * sizeof (WCHAR),
629 &done);
630
631 WideCharToMultiByte (CP_ACP, 0,
632 unicode_dll_name, len,
633 dll_name, len, 0, 0);
634 }
635 else
636 {
3cee93ac
CF
637 ReadProcessMemory (current_process_handle,
638 (LPCVOID) dll_name_ptr,
24e60978
SC
639 dll_name,
640 len,
641 &done);
642 }
24e60978 643 }
3cee93ac
CF
644
645 if (!dll_name)
646 return 1;
647
8e860359 648 register_loaded_dll (dll_name, (DWORD) event->lpBaseOfDll + 0x1000);
450005e7
CF
649
650 return 1;
651}
652
d3ff4a77
CF
653static int
654handle_unload_dll (void *dummy ATTRIBUTE_UNUSED)
655{
656 DWORD lpBaseOfDll = (DWORD) current_event.u.UnloadDll.lpBaseOfDll + 0x1000;
657 struct so_stuff *so;
658
659 for (so = &solib_start; so->next != NULL; so = so->next)
660 if (so->next->load_addr == lpBaseOfDll)
661 {
662 struct so_stuff *sodel = so->next;
663 so->next = sodel->next;
664 if (!so->next)
665 solib_end = so;
666 if (sodel->objfile)
667 free_objfile (sodel->objfile);
668 xfree(sodel);
669 return 1;
670 }
671 error ("Error: dll starting at 0x%lx not found.\n", (DWORD) lpBaseOfDll);
672
673 return 0;
674}
675
450005e7
CF
676/* Return name of last loaded DLL. */
677char *
9d3789f7 678child_solib_loaded_library_pathname (int pid ATTRIBUTE_UNUSED)
450005e7 679{
8e860359 680 return !solib_end || !solib_end->name[0] ? NULL : solib_end->name;
450005e7
CF
681}
682
683/* Clear list of loaded DLLs. */
684void
685child_clear_solibs (void)
686{
687 struct so_stuff *so, *so1 = solib_start.next;
688
689 while ((so = so1) != NULL)
690 {
691 so1 = so->next;
b8c9b27d 692 xfree (so);
450005e7
CF
693 }
694
695 solib_start.next = NULL;
d3ff4a77 696 solib_start.objfile = NULL;
450005e7
CF
697 solib_end = &solib_start;
698 max_dll_name_len = sizeof ("DLL Name") - 1;
699}
700
701/* Add DLL symbol information. */
d3ff4a77 702static struct objfile *
02e423b9 703solib_symbols_add (char *name, int from_tty, CORE_ADDR load_addr)
450005e7
CF
704{
705 struct section_addr_info section_addrs;
706
3cee93ac
CF
707 /* The symbols in a dll are offset by 0x1000, which is the
708 the offset from 0 of the first byte in an image - because
8a892701 709 of the file header and the section alignment. */
3cee93ac 710
8e860359 711 if (!name || !name[0])
d3ff4a77 712 return NULL;
450005e7
CF
713
714 memset (&section_addrs, 0, sizeof (section_addrs));
0aa9cf96 715 section_addrs.other[0].name = ".text";
8e860359 716 section_addrs.other[0].addr = load_addr;
d3ff4a77 717 return safe_symbol_file_add (name, from_tty, NULL, 0, OBJF_SHARED);
450005e7
CF
718}
719
720/* Load DLL symbol info. */
721void
7470a420 722dll_symbol_command (char *args, int from_tty)
450005e7 723{
8e860359 724 int n;
450005e7 725 dont_repeat ();
8e860359 726
450005e7
CF
727 if (args == NULL)
728 error ("dll-symbols requires a file name");
729
8e860359
CF
730 n = strlen (args);
731 if (n > 4 && strcasecmp (args + n - 4, ".dll") != 0)
732 {
733 char *newargs = (char *) alloca (n + 4 + 1);
734 strcpy (newargs, args);
735 strcat (newargs, ".dll");
736 args = newargs;
737 }
738
7470a420 739 safe_symbol_file_add (args, from_tty, NULL, 0, OBJF_SHARED | OBJF_USERLOADED);
8e860359 740}
450005e7
CF
741
742/* List currently loaded DLLs. */
743void
9d3789f7 744info_dll_command (char *ignore ATTRIBUTE_UNUSED, int from_tty ATTRIBUTE_UNUSED)
450005e7
CF
745{
746 struct so_stuff *so = &solib_start;
747
748 if (!so->next)
749 return;
750
751 printf ("%*s Load Address\n", -max_dll_name_len, "DLL Name");
752 while ((so = so->next) != NULL)
7c5c87c0 753 printf_filtered ("%*s %08lx\n", -max_dll_name_len, so->name, so->load_addr);
450005e7
CF
754
755 return;
24e60978
SC
756}
757
3cee93ac
CF
758/* Handle DEBUG_STRING output from child process.
759 Cygwin prepends its messages with a "cygwin:". Interpret this as
760 a Cygwin signal. Otherwise just print the string as a warning. */
761static int
762handle_output_debug_string (struct target_waitstatus *ourstatus)
763{
764 char *s;
765 int gotasig = FALSE;
766
767 if (!target_read_string
3a4b77d8 768 ((CORE_ADDR) current_event.u.DebugString.lpDebugStringData, &s, 1024, 0)
3cee93ac
CF
769 || !s || !*s)
770 return gotasig;
771
d3a09475 772 if (strncmp (s, CYGWIN_SIGNAL_STRING, sizeof (CYGWIN_SIGNAL_STRING) - 1) != 0)
3cee93ac 773 {
d3a09475 774 if (strncmp (s, "cYg", 3) != 0)
29fe111d 775 warning ("%s", s);
3cee93ac 776 }
d3a09475 777 else
3cee93ac
CF
778 {
779 char *p;
1e37c281
JM
780 int sig = strtol (s + sizeof (CYGWIN_SIGNAL_STRING) - 1, &p, 0);
781 gotasig = target_signal_from_host (sig);
0714f9bf
SS
782 ourstatus->value.sig = gotasig;
783 if (gotasig)
3cee93ac
CF
784 ourstatus->kind = TARGET_WAITKIND_STOPPED;
785 }
786
b8c9b27d 787 xfree (s);
3cee93ac
CF
788 return gotasig;
789}
24e60978 790
36339ecd 791static int
450005e7 792handle_exception (struct target_waitstatus *ourstatus)
24e60978 793{
3cee93ac 794 thread_info *th;
29fe111d 795 DWORD code = current_event.u.Exception.ExceptionRecord.ExceptionCode;
3cee93ac 796
29fe111d 797 ourstatus->kind = TARGET_WAITKIND_STOPPED;
8a892701 798
3cee93ac
CF
799 /* Record the context of the current thread */
800 th = thread_rec (current_event.dwThreadId, -1);
24e60978 801
29fe111d 802 switch (code)
24e60978 803 {
1ef980b9 804 case EXCEPTION_ACCESS_VIOLATION:
29fe111d 805 DEBUG_EXCEPT (("gdb: Target exception ACCESS_VIOLATION at 0x%08lx\n",
8e860359 806 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1ef980b9 807 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
8a892701 808 last_sig = SIGSEGV;
1ef980b9 809 break;
3b7c8b74
JM
810 case STATUS_FLOAT_UNDERFLOW:
811 case STATUS_FLOAT_DIVIDE_BY_ZERO:
812 case STATUS_FLOAT_OVERFLOW:
813 case STATUS_INTEGER_DIVIDE_BY_ZERO:
29fe111d 814 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08lx\n",
8e860359 815 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
3b7c8b74 816 ourstatus->value.sig = TARGET_SIGNAL_FPE;
29fe111d 817 last_sig = SIGFPE;
3b7c8b74 818 break;
1ef980b9 819 case STATUS_STACK_OVERFLOW:
29fe111d 820 DEBUG_EXCEPT (("gdb: Target exception STACK_OVERFLOW at 0x%08lx\n",
8e860359 821 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1ef980b9
SC
822 ourstatus->value.sig = TARGET_SIGNAL_SEGV;
823 break;
824 case EXCEPTION_BREAKPOINT:
29fe111d 825 DEBUG_EXCEPT (("gdb: Target exception BREAKPOINT at 0x%08lx\n",
8e860359 826 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1ef980b9
SC
827 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
828 break;
829 case DBG_CONTROL_C:
29fe111d 830 DEBUG_EXCEPT (("gdb: Target exception CONTROL_C at 0x%08lx\n",
8e860359 831 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1ef980b9 832 ourstatus->value.sig = TARGET_SIGNAL_INT;
8a892701 833 last_sig = SIGINT; /* FIXME - should check pass state */
1ef980b9
SC
834 break;
835 case EXCEPTION_SINGLE_STEP:
29fe111d 836 DEBUG_EXCEPT (("gdb: Target exception SINGLE_STEP at 0x%08lx\n",
8e860359 837 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
1ef980b9
SC
838 ourstatus->value.sig = TARGET_SIGNAL_TRAP;
839 break;
8227c82d 840 case EXCEPTION_ILLEGAL_INSTRUCTION:
29fe111d 841 DEBUG_EXCEPT (("gdb: Target exception SINGLE_ILL at 0x%08lx\n",
8e860359 842 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress));
8227c82d 843 ourstatus->value.sig = TARGET_SIGNAL_ILL;
8a892701 844 last_sig = SIGILL;
8227c82d 845 break;
1ef980b9 846 default:
02e423b9
CF
847 if (current_event.u.Exception.dwFirstChance)
848 return 0;
29fe111d 849 printf_unfiltered ("gdb: unknown target exception 0x%08lx at 0x%08lx\n",
3a4b77d8 850 current_event.u.Exception.ExceptionRecord.ExceptionCode,
8e860359 851 (DWORD) current_event.u.Exception.ExceptionRecord.ExceptionAddress);
24e60978 852 ourstatus->value.sig = TARGET_SIGNAL_UNKNOWN;
1ef980b9 853 break;
24e60978 854 }
24e60978 855 exception_count++;
36339ecd 856 return 1;
24e60978
SC
857}
858
3cee93ac
CF
859/* Resume all artificially suspended threads if we are continuing
860 execution */
861static BOOL
8a892701 862child_continue (DWORD continue_status, int id)
3cee93ac
CF
863{
864 int i;
865 thread_info *th;
866 BOOL res;
867
29fe111d 868 DEBUG_EVENTS (("ContinueDebugEvent (cpid=%ld, ctid=%ld, DBG_CONTINUE);\n",
3cee93ac 869 current_event.dwProcessId, current_event.dwThreadId));
0714f9bf
SS
870 res = ContinueDebugEvent (current_event.dwProcessId,
871 current_event.dwThreadId,
872 continue_status);
1e37c281 873 continue_status = 0;
0714f9bf 874 if (res)
3a4b77d8 875 for (th = &thread_head; (th = th->next) != NULL;)
29fe111d 876 if (((id == -1) || (id == (int) th->id)) && th->suspend_count)
3cee93ac
CF
877 {
878 for (i = 0; i < th->suspend_count; i++)
879 (void) ResumeThread (th->h);
880 th->suspend_count = 0;
881 }
882
883 return res;
884}
885
8a892701
CF
886/* Get the next event from the child. Return 1 if the event requires
887 handling by WFI (or whatever).
888 */
1e37c281 889static int
450005e7 890get_child_debug_event (int pid ATTRIBUTE_UNUSED, struct target_waitstatus *ourstatus)
1e37c281
JM
891{
892 BOOL debug_event;
8a892701
CF
893 DWORD continue_status, event_code;
894 thread_info *th = NULL;
895 static thread_info dummy_thread_info;
450005e7 896 int retval = 0;
1e37c281 897
9d3789f7
CF
898 last_sig = 0;
899
8a892701 900 if (!(debug_event = WaitForDebugEvent (&current_event, 1000)))
29fe111d 901 goto out;
1e37c281
JM
902
903 event_count++;
904 continue_status = DBG_CONTINUE;
1e37c281 905
8a892701 906 event_code = current_event.dwDebugEventCode;
450005e7 907 ourstatus->kind = TARGET_WAITKIND_SPURIOUS;
8a892701
CF
908
909 switch (event_code)
1e37c281
JM
910 {
911 case CREATE_THREAD_DEBUG_EVENT:
912 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%x code=%s)\n",
8a892701
CF
913 (unsigned) current_event.dwProcessId,
914 (unsigned) current_event.dwThreadId,
915 "CREATE_THREAD_DEBUG_EVENT"));
1e37c281 916 /* Record the existence of this thread */
8a892701
CF
917 th = child_add_thread (current_event.dwThreadId,
918 current_event.u.CreateThread.hThread);
1e37c281
JM
919 if (info_verbose)
920 printf_unfiltered ("[New %s]\n",
39f77062
KB
921 target_pid_to_str (
922 pid_to_ptid (current_event.dwThreadId)));
450005e7 923 retval = current_event.dwThreadId;
1e37c281
JM
924 break;
925
926 case EXIT_THREAD_DEBUG_EVENT:
927 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
928 (unsigned) current_event.dwProcessId,
929 (unsigned) current_event.dwThreadId,
930 "EXIT_THREAD_DEBUG_EVENT"));
1e37c281 931 child_delete_thread (current_event.dwThreadId);
8a892701 932 th = &dummy_thread_info;
1e37c281
JM
933 break;
934
935 case CREATE_PROCESS_DEBUG_EVENT:
936 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
937 (unsigned) current_event.dwProcessId,
938 (unsigned) current_event.dwThreadId,
939 "CREATE_PROCESS_DEBUG_EVENT"));
700b351b 940 CloseHandle (current_event.u.CreateProcessInfo.hFile);
1e37c281
JM
941 current_process_handle = current_event.u.CreateProcessInfo.hProcess;
942
9d3789f7 943 main_thread_id = current_event.dwThreadId;
1e37c281 944 /* Add the main thread */
9d3789f7 945#if 0
450005e7
CF
946 th = child_add_thread (current_event.dwProcessId,
947 current_event.u.CreateProcessInfo.hProcess);
9d3789f7
CF
948#endif
949 th = child_add_thread (main_thread_id,
8a892701 950 current_event.u.CreateProcessInfo.hThread);
9d3789f7 951 retval = ourstatus->value.related_pid = current_event.dwThreadId;
1e37c281
JM
952 break;
953
954 case EXIT_PROCESS_DEBUG_EVENT:
955 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
956 (unsigned) current_event.dwProcessId,
957 (unsigned) current_event.dwThreadId,
958 "EXIT_PROCESS_DEBUG_EVENT"));
1e37c281
JM
959 ourstatus->kind = TARGET_WAITKIND_EXITED;
960 ourstatus->value.integer = current_event.u.ExitProcess.dwExitCode;
961 CloseHandle (current_process_handle);
9d3789f7 962 retval = main_thread_id;
8a892701 963 break;
1e37c281
JM
964
965 case LOAD_DLL_DEBUG_EVENT:
966 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
967 (unsigned) current_event.dwProcessId,
968 (unsigned) current_event.dwThreadId,
969 "LOAD_DLL_DEBUG_EVENT"));
700b351b 970 CloseHandle (current_event.u.LoadDll.hFile);
8a892701 971 catch_errors (handle_load_dll, NULL, (char *) "", RETURN_MASK_ALL);
1e37c281 972 registers_changed (); /* mark all regs invalid */
450005e7
CF
973 ourstatus->kind = TARGET_WAITKIND_LOADED;
974 ourstatus->value.integer = 0;
9d3789f7 975 retval = main_thread_id;
1e37c281
JM
976 break;
977
978 case UNLOAD_DLL_DEBUG_EVENT:
979 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
980 (unsigned) current_event.dwProcessId,
981 (unsigned) current_event.dwThreadId,
982 "UNLOAD_DLL_DEBUG_EVENT"));
d3ff4a77
CF
983 catch_errors (handle_unload_dll, NULL, (char *) "", RETURN_MASK_ALL);
984 registers_changed (); /* mark all regs invalid */
985 /* ourstatus->kind = TARGET_WAITKIND_UNLOADED;
3bccec63 986 does not exist yet. */
d3ff4a77 987 break;
1e37c281
JM
988
989 case EXCEPTION_DEBUG_EVENT:
990 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
991 (unsigned) current_event.dwProcessId,
992 (unsigned) current_event.dwThreadId,
993 "EXCEPTION_DEBUG_EVENT"));
02e423b9
CF
994 if (handle_exception (ourstatus))
995 retval = current_event.dwThreadId;
1e37c281
JM
996 break;
997
8a892701 998 case OUTPUT_DEBUG_STRING_EVENT: /* message from the kernel */
1e37c281 999 DEBUG_EVENTS (("gdb: kernel event for pid=%d tid=%d code=%s)\n",
8a892701
CF
1000 (unsigned) current_event.dwProcessId,
1001 (unsigned) current_event.dwThreadId,
1002 "OUTPUT_DEBUG_STRING_EVENT"));
8e860359 1003 if (handle_output_debug_string (ourstatus))
9d3789f7 1004 retval = main_thread_id;
1e37c281 1005 break;
9d3789f7 1006
1e37c281 1007 default:
29fe111d
CF
1008 printf_unfiltered ("gdb: kernel event for pid=%ld tid=%ld\n",
1009 (DWORD) current_event.dwProcessId,
1010 (DWORD) current_event.dwThreadId);
1011 printf_unfiltered (" unknown event code %ld\n",
1e37c281
JM
1012 current_event.dwDebugEventCode);
1013 break;
1014 }
1015
450005e7 1016 if (!retval)
8a892701 1017 CHECK (child_continue (continue_status, -1));
450005e7 1018 else
9d3789f7 1019 {
8e860359 1020 current_thread = th ? : thread_rec (current_event.dwThreadId, TRUE);
39f77062 1021 inferior_ptid = pid_to_ptid (retval);
9d3789f7 1022 }
1e37c281
JM
1023
1024out:
450005e7 1025 return retval;
1e37c281
JM
1026}
1027
1e37c281 1028/* Wait for interesting events to occur in the target process. */
39f77062
KB
1029static ptid_t
1030child_wait (ptid_t ptid, struct target_waitstatus *ourstatus)
24e60978 1031{
39f77062
KB
1032 int pid = PIDGET (ptid);
1033
24e60978
SC
1034 /* We loop when we get a non-standard exception rather than return
1035 with a SPURIOUS because resume can try and step or modify things,
3cee93ac 1036 which needs a current_thread->h. But some of these exceptions mark
24e60978
SC
1037 the birth or death of threads, which mean that the current thread
1038 isn't necessarily what you think it is. */
1039
1040 while (1)
450005e7
CF
1041 {
1042 int retval = get_child_debug_event (pid, ourstatus);
1043 if (retval)
39f77062 1044 return pid_to_ptid (retval);
450005e7
CF
1045 else
1046 {
1047 int detach = 0;
3cee93ac 1048
450005e7
CF
1049 if (ui_loop_hook != NULL)
1050 detach = ui_loop_hook (0);
0714f9bf 1051
450005e7
CF
1052 if (detach)
1053 child_kill_inferior ();
1054 }
1055 }
24e60978
SC
1056}
1057
9d3789f7
CF
1058static void
1059do_initial_child_stuff (DWORD pid)
1060{
1061 extern int stop_after_trap;
1062
1063 last_sig = 0;
1064 event_count = 0;
1065 exception_count = 0;
1066 current_event.dwProcessId = pid;
1067 memset (&current_event, 0, sizeof (current_event));
1068 push_target (&child_ops);
1069 child_init_thread_list ();
1070 child_clear_solibs ();
1071 clear_proceed_status ();
1072 init_wait_for_inferior ();
1073
1074 target_terminal_init ();
1075 target_terminal_inferior ();
1076
1077 while (1)
1078 {
1079 stop_after_trap = 1;
1080 wait_for_inferior ();
1081 if (stop_signal != TARGET_SIGNAL_TRAP)
1082 resume (0, stop_signal);
1083 else
1084 break;
1085 }
1086 stop_after_trap = 0;
1087 return;
1088}
1089
02cc9f49
CV
1090/* Since Windows XP, detaching from a process is supported by Windows.
1091 The following code tries loading the appropriate functions dynamically.
1092 If loading these functions succeeds use them to actually detach from
1093 the inferior process, otherwise behave as usual, pretending that
1094 detach has worked. */
1095static BOOL WINAPI (*DebugSetProcessKillOnExit)(BOOL);
1096static BOOL WINAPI (*DebugActiveProcessStop)(DWORD);
1097
1098static int
1099has_detach_ability ()
1100{
1101 static HMODULE kernel32 = NULL;
1102
1103 if (!kernel32)
1104 kernel32 = LoadLibrary ("kernel32.dll");
1105 if (kernel32)
1106 {
1107 if (!DebugSetProcessKillOnExit)
1108 DebugSetProcessKillOnExit = GetProcAddress (kernel32,
1109 "DebugSetProcessKillOnExit");
1110 if (!DebugActiveProcessStop)
1111 DebugActiveProcessStop = GetProcAddress (kernel32,
1112 "DebugActiveProcessStop");
1113 if (DebugSetProcessKillOnExit && DebugActiveProcessStop)
1114 return 1;
1115 }
1116 return 0;
1117}
24e60978 1118
02cc9f49 1119/* Attach to process PID, then initialize for debugging it. */
24e60978 1120static void
fba45db2 1121child_attach (char *args, int from_tty)
24e60978
SC
1122{
1123 BOOL ok;
559e75c0 1124 DWORD pid;
24e60978
SC
1125
1126 if (!args)
1127 error_no_arg ("process-id to attach");
1128
559e75c0 1129 pid = strtoul (args, 0, 0);
9d3789f7 1130 ok = DebugActiveProcess (pid);
24e60978
SC
1131
1132 if (!ok)
1133 error ("Can't attach to process.");
1134
02cc9f49
CV
1135 if (has_detach_ability ())
1136 {
1137 attach_flag = 1;
1138 DebugSetProcessKillOnExit (FALSE);
1139 }
1140
24e60978
SC
1141 if (from_tty)
1142 {
1143 char *exec_file = (char *) get_exec_file (0);
1144
1145 if (exec_file)
1146 printf_unfiltered ("Attaching to program `%s', %s\n", exec_file,
39f77062 1147 target_pid_to_str (pid_to_ptid (pid)));
24e60978
SC
1148 else
1149 printf_unfiltered ("Attaching to %s\n",
39f77062 1150 target_pid_to_str (pid_to_ptid (pid)));
24e60978
SC
1151
1152 gdb_flush (gdb_stdout);
1153 }
1154
9d3789f7
CF
1155 do_initial_child_stuff (pid);
1156 target_terminal_ours ();
24e60978
SC
1157}
1158
24e60978 1159static void
29fe111d 1160child_detach (char *args ATTRIBUTE_UNUSED, int from_tty)
24e60978 1161{
02cc9f49
CV
1162 int detached = 1;
1163
1164 if (has_detach_ability ())
1165 {
1166 delete_command (NULL, 0);
1167 child_continue (DBG_CONTINUE, -1);
1168 if (!DebugActiveProcessStop (current_event.dwProcessId))
3bccec63 1169 {
02cc9f49
CV
1170 error ("Can't detach process %lu (error %lu)",
1171 current_event.dwProcessId, GetLastError ());
1172 detached = 0;
3bccec63 1173 }
02cc9f49
CV
1174 DebugSetProcessKillOnExit (FALSE);
1175 }
1176 if (detached && from_tty)
24e60978
SC
1177 {
1178 char *exec_file = get_exec_file (0);
1179 if (exec_file == 0)
1180 exec_file = "";
02cc9f49
CV
1181 printf_unfiltered ("Detaching from program: %s, Pid %lu\n", exec_file,
1182 current_event.dwProcessId);
24e60978
SC
1183 gdb_flush (gdb_stdout);
1184 }
39f77062 1185 inferior_ptid = null_ptid;
24e60978
SC
1186 unpush_target (&child_ops);
1187}
1188
24e60978
SC
1189/* Print status information about what we're accessing. */
1190
1191static void
29fe111d 1192child_files_info (struct target_ops *ignore ATTRIBUTE_UNUSED)
24e60978
SC
1193{
1194 printf_unfiltered ("\tUsing the running image of %s %s.\n",
39f77062 1195 attach_flag ? "attached" : "child", target_pid_to_str (inferior_ptid));
24e60978
SC
1196}
1197
1198/* ARGSUSED */
1199static void
29fe111d 1200child_open (char *arg ATTRIBUTE_UNUSED, int from_tty ATTRIBUTE_UNUSED)
24e60978
SC
1201{
1202 error ("Use the \"run\" command to start a Unix child process.");
1203}
1204
39f77062 1205/* Start an inferior win32 child process and sets inferior_ptid to its pid.
24e60978
SC
1206 EXEC_FILE is the file to run.
1207 ALLARGS is a string containing the arguments to the program.
1208 ENV is the environment vector to pass. Errors reported with error(). */
1209
24e60978 1210static void
fba45db2 1211child_create_inferior (char *exec_file, char *allargs, char **env)
24e60978 1212{
1750a5ef
SC
1213 char real_path[MAXPATHLEN];
1214 char *winenv;
1215 char *temp;
3a4b77d8 1216 int envlen;
1750a5ef 1217 int i;
24e60978
SC
1218 STARTUPINFO si;
1219 PROCESS_INFORMATION pi;
24e60978
SC
1220 BOOL ret;
1221 DWORD flags;
eb708f2e 1222 char *args;
24e60978
SC
1223
1224 if (!exec_file)
450005e7 1225 error ("No executable specified, use `target exec'.\n");
24e60978
SC
1226
1227 memset (&si, 0, sizeof (si));
1228 si.cb = sizeof (si);
1229
29fe111d 1230 cygwin_conv_to_win32_path (exec_file, real_path);
24e60978 1231
3cee93ac 1232 flags = DEBUG_ONLY_THIS_PROCESS;
24e60978
SC
1233
1234 if (new_group)
1235 flags |= CREATE_NEW_PROCESS_GROUP;
1236
1237 if (new_console)
1238 flags |= CREATE_NEW_CONSOLE;
1239
3d78f532
SC
1240 args = alloca (strlen (real_path) + strlen (allargs) + 2);
1241
1242 strcpy (args, real_path);
eb708f2e 1243
eb708f2e
SC
1244 strcat (args, " ");
1245 strcat (args, allargs);
1246
e88c49c3
DE
1247 /* Prepare the environment vars for CreateProcess. */
1248 {
1249 /* This code use to assume all env vars were file names and would
1250 translate them all to win32 style. That obviously doesn't work in the
2dcfc9c7
DE
1251 general case. The current rule is that we only translate PATH.
1252 We need to handle PATH because we're about to call CreateProcess and
1253 it uses PATH to find DLL's. Fortunately PATH has a well-defined value
1254 in both posix and win32 environments. cygwin.dll will change it back
1255 to posix style if necessary. */
e88c49c3
DE
1256
1257 static const char *conv_path_names[] =
3a4b77d8
JM
1258 {
1259 "PATH=",
1260 0
1261 };
e88c49c3
DE
1262
1263 /* CreateProcess takes the environment list as a null terminated set of
1264 strings (i.e. two nulls terminate the list). */
1265
1266 /* Get total size for env strings. */
1267 for (envlen = 0, i = 0; env[i] && *env[i]; i++)
1268 {
2dcfc9c7 1269 int j, len;
e88c49c3 1270
2dcfc9c7
DE
1271 for (j = 0; conv_path_names[j]; j++)
1272 {
1273 len = strlen (conv_path_names[j]);
1274 if (strncmp (conv_path_names[j], env[i], len) == 0)
e88c49c3 1275 {
29fe111d 1276 if (cygwin_posix_path_list_p (env[i] + len))
2dcfc9c7 1277 envlen += len
29fe111d 1278 + cygwin_posix_to_win32_path_list_buf_size (env[i] + len);
2dcfc9c7
DE
1279 else
1280 envlen += strlen (env[i]) + 1;
1281 break;
e88c49c3 1282 }
e88c49c3 1283 }
2dcfc9c7 1284 if (conv_path_names[j] == NULL)
e88c49c3
DE
1285 envlen += strlen (env[i]) + 1;
1286 }
1287
1288 winenv = alloca (envlen + 1);
1289
1290 /* Copy env strings into new buffer. */
3cee93ac 1291 for (temp = winenv, i = 0; env[i] && *env[i]; i++)
e88c49c3 1292 {
2dcfc9c7 1293 int j, len;
e88c49c3 1294
2dcfc9c7
DE
1295 for (j = 0; conv_path_names[j]; j++)
1296 {
1297 len = strlen (conv_path_names[j]);
1298 if (strncmp (conv_path_names[j], env[i], len) == 0)
e88c49c3 1299 {
29fe111d 1300 if (cygwin_posix_path_list_p (env[i] + len))
e88c49c3
DE
1301 {
1302 memcpy (temp, env[i], len);
29fe111d 1303 cygwin_posix_to_win32_path_list (env[i] + len, temp + len);
e88c49c3 1304 }
2dcfc9c7
DE
1305 else
1306 strcpy (temp, env[i]);
1307 break;
e88c49c3 1308 }
e88c49c3 1309 }
2dcfc9c7 1310 if (conv_path_names[j] == NULL)
e88c49c3 1311 strcpy (temp, env[i]);
2dcfc9c7 1312
e88c49c3
DE
1313 temp += strlen (temp) + 1;
1314 }
1315
1316 /* Final nil string to terminate new env. */
1317 *temp = 0;
1318 }
1750a5ef 1319
1750a5ef 1320 ret = CreateProcess (0,
3a4b77d8 1321 args, /* command line */
24e60978
SC
1322 NULL, /* Security */
1323 NULL, /* thread */
1324 TRUE, /* inherit handles */
1325 flags, /* start flags */
1750a5ef 1326 winenv,
24e60978
SC
1327 NULL, /* current directory */
1328 &si,
1329 &pi);
1330 if (!ret)
3a4b77d8 1331 error ("Error creating process %s, (error %d)\n", exec_file, GetLastError ());
24e60978 1332
700b351b
CF
1333 CloseHandle (pi.hThread);
1334 CloseHandle (pi.hProcess);
9d3789f7 1335 do_initial_child_stuff (pi.dwProcessId);
d3a09475 1336
8e860359 1337 /* child_continue (DBG_CONTINUE, -1); */
1e37c281 1338 proceed ((CORE_ADDR) - 1, TARGET_SIGNAL_0, 0);
24e60978
SC
1339}
1340
1341static void
fba45db2 1342child_mourn_inferior (void)
24e60978 1343{
8a892701 1344 (void) child_continue (DBG_CONTINUE, -1);
24e60978
SC
1345 unpush_target (&child_ops);
1346 generic_mourn_inferior ();
1347}
1348
24e60978
SC
1349/* Send a SIGINT to the process group. This acts just like the user typed a
1350 ^C on the controlling terminal. */
1351
b607efe7 1352static void
fba45db2 1353child_stop (void)
24e60978 1354{
1ef980b9 1355 DEBUG_EVENTS (("gdb: GenerateConsoleCtrlEvent (CTRLC_EVENT, 0)\n"));
1e37c281 1356 CHECK (GenerateConsoleCtrlEvent (CTRL_C_EVENT, current_event.dwProcessId));
3a4b77d8 1357 registers_changed (); /* refresh register state */
24e60978
SC
1358}
1359
1360int
eb708f2e 1361child_xfer_memory (CORE_ADDR memaddr, char *our, int len,
56c40d46 1362 int write, struct mem_attrib *mem ATTRIBUTE_UNUSED,
aea02b6b 1363 struct target_ops *target ATTRIBUTE_UNUSED)
24e60978
SC
1364{
1365 DWORD done;
1366 if (write)
1367 {
29fe111d
CF
1368 DEBUG_MEM (("gdb: write target memory, %d bytes at 0x%08lx\n",
1369 len, (DWORD) memaddr));
3cee93ac
CF
1370 WriteProcessMemory (current_process_handle, (LPVOID) memaddr, our,
1371 len, &done);
1372 FlushInstructionCache (current_process_handle, (LPCVOID) memaddr, len);
24e60978
SC
1373 }
1374 else
1375 {
29fe111d
CF
1376 DEBUG_MEM (("gdb: read target memory, %d bytes at 0x%08lx\n",
1377 len, (DWORD) memaddr));
3cee93ac
CF
1378 ReadProcessMemory (current_process_handle, (LPCVOID) memaddr, our, len,
1379 &done);
24e60978
SC
1380 }
1381 return done;
1382}
1383
1384void
1385child_kill_inferior (void)
1386{
3cee93ac
CF
1387 CHECK (TerminateProcess (current_process_handle, 0));
1388
b5edcb45
ILT
1389 for (;;)
1390 {
8a892701 1391 if (!child_continue (DBG_CONTINUE, -1))
b5edcb45 1392 break;
3cee93ac 1393 if (!WaitForDebugEvent (&current_event, INFINITE))
b5edcb45 1394 break;
3cee93ac 1395 if (current_event.dwDebugEventCode == EXIT_PROCESS_DEBUG_EVENT)
b5edcb45
ILT
1396 break;
1397 }
1398
3cee93ac
CF
1399 CHECK (CloseHandle (current_process_handle));
1400
1401 /* this may fail in an attached process so don't check. */
1402 (void) CloseHandle (current_thread->h);
3a4b77d8 1403 target_mourn_inferior (); /* or just child_mourn_inferior? */
24e60978
SC
1404}
1405
1406void
39f77062 1407child_resume (ptid_t ptid, int step, enum target_signal sig)
24e60978 1408{
3cee93ac 1409 thread_info *th;
8a892701 1410 DWORD continue_status = last_sig > 0 && last_sig < NSIG ?
8e860359 1411 DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE;
39f77062 1412 int pid = PIDGET (ptid);
8a892701
CF
1413
1414 last_sig = 0;
24e60978 1415
3cee93ac
CF
1416 DEBUG_EXEC (("gdb: child_resume (pid=%d, step=%d, sig=%d);\n",
1417 pid, step, sig));
1418
1419 /* Get context for currently selected thread */
1420 th = thread_rec (current_event.dwThreadId, FALSE);
450005e7 1421 if (th)
24e60978 1422 {
450005e7
CF
1423 if (step)
1424 {
1425 /* Single step by setting t bit */
1426 child_fetch_inferior_registers (PS_REGNUM);
1427 th->context.EFlags |= FLAG_TRACE_BIT;
1428 }
24e60978 1429
450005e7
CF
1430 if (th->context.ContextFlags)
1431 {
1432 CHECK (SetThreadContext (th->h, &th->context));
1433 th->context.ContextFlags = 0;
1434 }
24e60978
SC
1435 }
1436
3cee93ac
CF
1437 /* Allow continuing with the same signal that interrupted us.
1438 Otherwise complain. */
24e60978 1439
8a892701 1440 child_continue (continue_status, pid);
24e60978
SC
1441}
1442
1443static void
fba45db2 1444child_prepare_to_store (void)
24e60978
SC
1445{
1446 /* Do nothing, since we can store individual regs */
1447}
1448
1449static int
fba45db2 1450child_can_run (void)
24e60978
SC
1451{
1452 return 1;
1453}
1454
1455static void
9d3789f7 1456child_close (int x ATTRIBUTE_UNUSED)
24e60978 1457{
39f77062 1458 DEBUG_EVENTS (("gdb: child_close, inferior_ptid=%d\n",
3bccec63 1459 PIDGET (inferior_ptid)));
24e60978 1460}
1ef980b9 1461
3a4b77d8 1462struct target_ops child_ops;
c719b714 1463
3a4b77d8
JM
1464static void
1465init_child_ops (void)
24e60978 1466{
3a4b77d8
JM
1467 child_ops.to_shortname = "child";
1468 child_ops.to_longname = "Win32 child process";
1469 child_ops.to_doc = "Win32 child process (started by the \"run\" command).";
1470 child_ops.to_open = child_open;
1471 child_ops.to_close = child_close;
1472 child_ops.to_attach = child_attach;
1473 child_ops.to_detach = child_detach;
1474 child_ops.to_resume = child_resume;
1475 child_ops.to_wait = child_wait;
1476 child_ops.to_fetch_registers = child_fetch_inferior_registers;
1477 child_ops.to_store_registers = child_store_inferior_registers;
1478 child_ops.to_prepare_to_store = child_prepare_to_store;
1479 child_ops.to_xfer_memory = child_xfer_memory;
1480 child_ops.to_files_info = child_files_info;
1481 child_ops.to_insert_breakpoint = memory_insert_breakpoint;
1482 child_ops.to_remove_breakpoint = memory_remove_breakpoint;
1483 child_ops.to_terminal_init = terminal_init_inferior;
1484 child_ops.to_terminal_inferior = terminal_inferior;
1485 child_ops.to_terminal_ours_for_output = terminal_ours_for_output;
1486 child_ops.to_terminal_ours = terminal_ours;
1487 child_ops.to_terminal_info = child_terminal_info;
1488 child_ops.to_kill = child_kill_inferior;
1489 child_ops.to_load = 0;
1490 child_ops.to_lookup_symbol = 0;
1491 child_ops.to_create_inferior = child_create_inferior;
1492 child_ops.to_mourn_inferior = child_mourn_inferior;
1493 child_ops.to_can_run = child_can_run;
1494 child_ops.to_notice_signals = 0;
1495 child_ops.to_thread_alive = win32_child_thread_alive;
d3a09475 1496 child_ops.to_pid_to_str = cygwin_pid_to_str;
3a4b77d8
JM
1497 child_ops.to_stop = child_stop;
1498 child_ops.to_stratum = process_stratum;
1499 child_ops.DONT_USE = 0;
1500 child_ops.to_has_all_memory = 1;
1501 child_ops.to_has_memory = 1;
1502 child_ops.to_has_stack = 1;
1503 child_ops.to_has_registers = 1;
1504 child_ops.to_has_execution = 1;
1505 child_ops.to_sections = 0;
1506 child_ops.to_sections_end = 0;
1507 child_ops.to_magic = OPS_MAGIC;
c719b714 1508}
24e60978
SC
1509
1510void
fba45db2 1511_initialize_inftarg (void)
24e60978 1512{
fa58ee11
EZ
1513 struct cmd_list_element *c;
1514
3a4b77d8 1515 init_child_ops ();
1ef980b9 1516
fa58ee11
EZ
1517 c = add_com ("dll-symbols", class_files, dll_symbol_command,
1518 "Load dll library symbols from FILE.");
1519 c->completer = filename_completer;
450005e7
CF
1520
1521 add_com_alias ("sharedlibrary", "dll-symbols", class_alias, 1);
1522
1523 add_show_from_set (add_set_cmd ("new-console", class_support, var_boolean,
8e860359
CF
1524 (char *) &new_console,
1525 "Set creation of new console when creating child process.",
1526 &setlist),
1527 &showlist);
24e60978 1528
450005e7 1529 add_show_from_set (add_set_cmd ("new-group", class_support, var_boolean,
8e860359
CF
1530 (char *) &new_group,
1531 "Set creation of new group when creating child process.",
1532 &setlist),
1533 &showlist);
24e60978 1534
450005e7 1535 add_show_from_set (add_set_cmd ("debugexec", class_support, var_boolean,
8e860359
CF
1536 (char *) &debug_exec,
1537 "Set whether to display execution in child process.",
1538 &setlist),
1539 &showlist);
1ef980b9 1540
450005e7 1541 add_show_from_set (add_set_cmd ("debugevents", class_support, var_boolean,
8e860359
CF
1542 (char *) &debug_events,
1543 "Set whether to display kernel events in child process.",
1544 &setlist),
1545 &showlist);
1ef980b9 1546
450005e7 1547 add_show_from_set (add_set_cmd ("debugmemory", class_support, var_boolean,
8e860359
CF
1548 (char *) &debug_memory,
1549 "Set whether to display memory accesses in child process.",
1550 &setlist),
1551 &showlist);
1ef980b9 1552
450005e7 1553 add_show_from_set (add_set_cmd ("debugexceptions", class_support, var_boolean,
8e860359
CF
1554 (char *) &debug_exceptions,
1555 "Set whether to display kernel exceptions in child process.",
1556 &setlist),
1557 &showlist);
1ef980b9 1558
450005e7
CF
1559 add_info ("dll", info_dll_command, "Status of loaded DLLs.");
1560 add_info_alias ("sharedlibrary", "dll", 1);
1561
24e60978
SC
1562 add_target (&child_ops);
1563}
3cee93ac
CF
1564
1565/* Determine if the thread referenced by "pid" is alive
1566 by "polling" it. If WaitForSingleObject returns WAIT_OBJECT_0
1567 it means that the pid has died. Otherwise it is assumed to be alive. */
1568static int
39f77062 1569win32_child_thread_alive (ptid_t ptid)
3cee93ac 1570{
39f77062
KB
1571 int pid = PIDGET (ptid);
1572
3a4b77d8
JM
1573 return WaitForSingleObject (thread_rec (pid, FALSE)->h, 0) == WAIT_OBJECT_0 ?
1574 FALSE : TRUE;
3cee93ac
CF
1575}
1576
1577/* Convert pid to printable format. */
1578char *
39f77062 1579cygwin_pid_to_str (ptid_t ptid)
3cee93ac
CF
1580{
1581 static char buf[80];
39f77062
KB
1582 int pid = PIDGET (ptid);
1583
29fe111d 1584 if ((DWORD) pid == current_event.dwProcessId)
3cee93ac
CF
1585 sprintf (buf, "process %d", pid);
1586 else
29fe111d 1587 sprintf (buf, "thread %ld.0x%x", current_event.dwProcessId, pid);
3cee93ac
CF
1588 return buf;
1589}
8e860359
CF
1590
1591static int
1592core_dll_symbols_add (char *dll_name, DWORD base_addr)
1593{
1594 struct objfile *objfile;
1595 char *objfile_basename;
1596 const char *dll_basename;
1597
1598 if (!(dll_basename = strrchr (dll_name, '/')))
1599 dll_basename = dll_name;
1600 else
1601 dll_basename++;
1602
1603 ALL_OBJFILES (objfile)
1604 {
1605 objfile_basename = strrchr (objfile->name, '/');
1606
1607 if (objfile_basename &&
1608 strcmp (dll_basename, objfile_basename + 1) == 0)
1609 {
1610 printf_unfiltered ("%08lx:%s (symbols previously loaded)\n",
1611 base_addr, dll_name);
1612 goto out;
1613 }
1614 }
1615
1616 register_loaded_dll (dll_name, base_addr + 0x1000);
02e423b9 1617 solib_symbols_add (dll_name, 0, (CORE_ADDR) base_addr + 0x1000);
8e860359
CF
1618
1619out:
1620 return 1;
1621}
1622
1623typedef struct
1624{
1625 struct target_ops *target;
1626 bfd_vma addr;
1627}
1628map_code_section_args;
1629
1630static void
554cb486 1631map_single_dll_code_section (bfd * abfd, asection * sect, void *obj)
8e860359
CF
1632{
1633 int old;
1634 int update_coreops;
1635 struct section_table *new_target_sect_ptr;
1636
1637 map_code_section_args *args = (map_code_section_args *) obj;
1638 struct target_ops *target = args->target;
1639 if (sect->flags & SEC_CODE)
1640 {
1641 update_coreops = core_ops.to_sections == target->to_sections;
1642
1643 if (target->to_sections)
1644 {
1645 old = target->to_sections_end - target->to_sections;
1646 target->to_sections = (struct section_table *)
1647 xrealloc ((char *) target->to_sections,
1648 (sizeof (struct section_table)) * (1 + old));
1649 }
1650 else
1651 {
1652 old = 0;
1653 target->to_sections = (struct section_table *)
1654 xmalloc ((sizeof (struct section_table)));
1655 }
1656 target->to_sections_end = target->to_sections + (1 + old);
1657
1658 /* Update the to_sections field in the core_ops structure
3bccec63 1659 if needed. */
8e860359
CF
1660 if (update_coreops)
1661 {
1662 core_ops.to_sections = target->to_sections;
1663 core_ops.to_sections_end = target->to_sections_end;
1664 }
1665 new_target_sect_ptr = target->to_sections + old;
1666 new_target_sect_ptr->addr = args->addr + bfd_section_vma (abfd, sect);
1667 new_target_sect_ptr->endaddr = args->addr + bfd_section_vma (abfd, sect) +
1668 bfd_section_size (abfd, sect);;
1669 new_target_sect_ptr->the_bfd_section = sect;
1670 new_target_sect_ptr->bfd = abfd;
1671 }
1672}
1673
1674static int
1675dll_code_sections_add (const char *dll_name, int base_addr, struct target_ops *target)
1676{
1677 bfd *dll_bfd;
1678 map_code_section_args map_args;
1679 asection *lowest_sect;
1680 char *name;
1681 if (dll_name == NULL || target == NULL)
1682 return 0;
66ed1d85 1683 name = xstrdup (dll_name);
8e860359
CF
1684 dll_bfd = bfd_openr (name, "pei-i386");
1685 if (dll_bfd == NULL)
1686 return 0;
1687
1688 if (bfd_check_format (dll_bfd, bfd_object))
1689 {
1690 lowest_sect = bfd_get_section_by_name (dll_bfd, ".text");
1691 if (lowest_sect == NULL)
1692 return 0;
1693 map_args.target = target;
1694 map_args.addr = base_addr - bfd_section_vma (dll_bfd, lowest_sect);
1695
554cb486 1696 bfd_map_over_sections (dll_bfd, &map_single_dll_code_section, (void *) (&map_args));
8e860359
CF
1697 }
1698
1699 return 1;
1700}
1701
1702static void
554cb486 1703core_section_load_dll_symbols (bfd * abfd, asection * sect, void *obj)
8e860359
CF
1704{
1705 struct target_ops *target = (struct target_ops *) obj;
1706
1707 DWORD base_addr;
1708
1709 int dll_name_size;
1710 char *dll_name = NULL;
1711 char *buf = NULL;
1712 struct win32_pstatus *pstatus;
1713 char *p;
1714
1715 if (strncmp (sect->name, ".module", 7))
1716 return;
1717
1718 buf = (char *) xmalloc (sect->_raw_size + 1);
1719 if (!buf)
1720 {
1721 printf_unfiltered ("memory allocation failed for %s\n", sect->name);
1722 goto out;
1723 }
1724 if (!bfd_get_section_contents (abfd, sect, buf, 0, sect->_raw_size))
1725 goto out;
1726
1727 pstatus = (struct win32_pstatus *) buf;
1728
1729 memmove (&base_addr, &(pstatus->data.module_info.base_address), sizeof (base_addr));
1730 dll_name_size = pstatus->data.module_info.module_name_size;
1731 if (offsetof (struct win32_pstatus, data.module_info.module_name) + dll_name_size > sect->_raw_size)
1732 goto out;
1733
1734 dll_name = (char *) xmalloc (dll_name_size + 1);
1735 if (!dll_name)
1736 {
1737 printf_unfiltered ("memory allocation failed for %s\n", sect->name);
1738 goto out;
1739 }
1740 strncpy (dll_name, pstatus->data.module_info.module_name, dll_name_size);
1741
1742 while ((p = strchr (dll_name, '\\')))
1743 *p = '/';
1744
1745 if (!core_dll_symbols_add (dll_name, (DWORD) base_addr))
1746 printf_unfiltered ("%s: Failed to load dll symbols.\n", dll_name);
1747
1748 if (!dll_code_sections_add (dll_name, (DWORD) base_addr + 0x1000, target))
1749 printf_unfiltered ("%s: Failed to map dll code sections.\n", dll_name);
1750
1751out:
1752 if (buf)
b8c9b27d 1753 xfree (buf);
8e860359 1754 if (dll_name)
b8c9b27d 1755 xfree (dll_name);
8e860359
CF
1756 return;
1757}
1758
1759void
990f9fe3 1760child_solib_add (char *filename ATTRIBUTE_UNUSED, int from_tty, struct target_ops *target, int readsyms)
8e860359 1761{
990f9fe3
FF
1762 if (!readsyms)
1763 return;
8e860359
CF
1764 if (core_bfd)
1765 {
1766 child_clear_solibs ();
1767 bfd_map_over_sections (core_bfd, &core_section_load_dll_symbols, target);
1768 }
1769 else
1770 {
1771 if (solib_end && solib_end->name)
d3ff4a77 1772 solib_end->objfile = solib_symbols_add (solib_end->name, from_tty,
3bccec63 1773 solib_end->load_addr);
8e860359
CF
1774 }
1775}
1776
1777static void
1778fetch_elf_core_registers (char *core_reg_sect,
1779 unsigned core_reg_size,
1780 int which,
1781 CORE_ADDR reg_addr)
1782{
1783 int r;
1784 if (core_reg_size < sizeof (CONTEXT))
1785 {
1786 error ("Core file register section too small (%u bytes).", core_reg_size);
1787 return;
1788 }
1789 for (r = 0; r < NUM_REGS; r++)
1790 supply_register (r, core_reg_sect + mappings[r]);
1791}
1792
1793static struct core_fns win32_elf_core_fns =
1794{
1795 bfd_target_elf_flavour,
1796 default_check_format,
1797 default_core_sniffer,
1798 fetch_elf_core_registers,
1799 NULL
1800};
1801
1802void
0613c401 1803_initialize_core_win32 (void)
8e860359
CF
1804{
1805 add_core_fns (&win32_elf_core_fns);
1806}
2a3d5645
CF
1807
1808void
1809_initialize_check_for_gdb_ini (void)
1810{
1811 char *homedir;
1812 if (inhibit_gdbinit)
1813 return;
1814
1815 homedir = getenv ("HOME");
1816 if (homedir)
1817 {
1818 char *p;
1819 char *oldini = (char *) alloca (strlen (homedir) +
1820 sizeof ("/gdb.ini"));
1821 strcpy (oldini, homedir);
1822 p = strchr (oldini, '\0');
1823 if (p > oldini && p[-1] != '/')
1824 *p++ = '/';
1825 strcpy (p, "gdb.ini");
1826 if (access (oldini, 0) == 0)
1827 {
1828 int len = strlen (oldini);
1829 char *newini = alloca (len + 1);
1830 sprintf (newini, "%.*s.gdbinit", len - (sizeof ("gdb.ini") - 1), oldini);
1831 warning ("obsolete '%s' found. Rename to '%s'.", oldini, newini);
1832 }
1833 }
1834}
This page took 0.427033 seconds and 4 git commands to generate.