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